diff options
Diffstat (limited to 'src')
247 files changed, 4255 insertions, 1034 deletions
diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index aa5be612e..e6e02c2d6 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -86,7 +86,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { protected TimeZone getTimeZone(long deviceId, String defaultTimeZone) { TimeZone result = TimeZone.getTimeZone(defaultTimeZone); - String timeZoneName = identityManager.lookupAttributeString(deviceId, "decoder.timezone", null, true); + String timeZoneName = identityManager.lookupAttributeString(deviceId, "decoder.timezone", null, false, true); if (timeZoneName != null) { result = TimeZone.getTimeZone(timeZoneName); } else { @@ -143,7 +143,13 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } public DeviceSession getDeviceSession(Channel channel, SocketAddress remoteAddress, String... uniqueIds) { + return getDeviceSession(channel, remoteAddress, false, uniqueIds); + } + + public DeviceSession getDeviceSession( + Channel channel, SocketAddress remoteAddress, boolean ignoreCache, String... uniqueIds) { if (channel != null && BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) != null + || ignoreCache || config.getBoolean(getProtocolName() + ".ignoreSessionCache") || config.getBoolean("decoder.ignoreSessionCache")) { long deviceId = findDeviceId(remoteAddress, uniqueIds); if (deviceId != 0) { diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index d7625e4b8..b6df07b98 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,25 +22,32 @@ import io.netty.channel.ChannelPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.Command; -import org.traccar.model.Device; public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(BaseProtocolEncoder.class); + private static final String PROTOCOL_UNKNOWN = "unknown"; + + private final Protocol protocol; + + public BaseProtocolEncoder(Protocol protocol) { + this.protocol = protocol; + } + + public String getProtocolName() { + return protocol != null ? protocol.getName() : PROTOCOL_UNKNOWN; + } + protected String getUniqueId(long deviceId) { return Context.getIdentityManager().getById(deviceId).getUniqueId(); } protected void initDevicePassword(Command command, String defaultPassword) { if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { - Device device = Context.getIdentityManager().getById(command.getDeviceId()); - String password = device.getString(Command.KEY_DEVICE_PASSWORD); - if (password != null) { - command.set(Command.KEY_DEVICE_PASSWORD, password); - } else { - command.set(Command.KEY_DEVICE_PASSWORD, defaultPassword); - } + String password = Context.getIdentityManager() + .getDevicePassword(command.getDeviceId(), getProtocolName(), defaultPassword); + command.set(Command.KEY_DEVICE_PASSWORD, password); } } diff --git a/src/main/java/org/traccar/StringProtocolEncoder.java b/src/main/java/org/traccar/StringProtocolEncoder.java index 1945ae174..d9acce7f0 100644 --- a/src/main/java/org/traccar/StringProtocolEncoder.java +++ b/src/main/java/org/traccar/StringProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,10 @@ import java.util.Map; public abstract class StringProtocolEncoder extends BaseProtocolEncoder { + public StringProtocolEncoder(Protocol protocol) { + super(protocol); + } + public interface ValueFormatter { String formatValue(String key, Object value); } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index a000329e2..2c5dcefd5 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -197,8 +197,9 @@ public final class Keys { "time.protocols", String.class); /** - * Replaces coordinates with last known if change is less than a 'coordinates.error' meters. Helps to avoid - * coordinates jumps during parking period. + * Replaces coordinates with last known if change is less than a 'coordinates.minError' meters + * or more than a 'coordinates.maxError' meters. Helps to avoid coordinates jumps during parking period + * or jumps to zero coordinates. */ public static final ConfigKey COORDINATES_FILTER = new ConfigKey( "coordinates.filter", Boolean.class); @@ -214,7 +215,7 @@ public final class Keys { * Position is also marked as 'invalid'. */ public static final ConfigKey COORDINATES_MAX_ERROR = new ConfigKey( - "filter.maxError", Integer.class); + "coordinates.maxError", Integer.class); /** * Enable to save device IP addresses information. Disabled by default. diff --git a/src/main/java/org/traccar/database/ConnectionManager.java b/src/main/java/org/traccar/database/ConnectionManager.java index 8bae1ea93..dd0071143 100644 --- a/src/main/java/org/traccar/database/ConnectionManager.java +++ b/src/main/java/org/traccar/database/ConnectionManager.java @@ -157,7 +157,7 @@ public class ConnectionManager { event = Main.getInjector().getInstance(OverspeedEventHandler.class) .updateOverspeedState(deviceState, Context.getDeviceManager(). - lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, false)); + lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, true, false)); if (event != null) { result.putAll(event); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index de4607d1f..fa95adeb2 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.Context; +import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.DeviceState; import org.traccar.model.DeviceAccumulators; @@ -114,6 +115,24 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity return devicesByUniqueId.get(uniqueId); } + @Override + public String getDevicePassword(long id, String protocol, String defaultPassword) { + + String password = lookupAttributeString(id, Command.KEY_DEVICE_PASSWORD, null, false, false); + if (password != null) { + return password; + } + + if (protocol != null) { + password = Context.getConfig().getString(protocol + "." + Command.KEY_DEVICE_PASSWORD); + if (password != null) { + return password; + } + } + + return defaultPassword; + } + public Device getDeviceByPhone(String phone) { return devicesByPhone.get(phone); } @@ -312,8 +331,8 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity @Override public boolean lookupAttributeBoolean( - long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig) { + Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); if (result != null) { return result instanceof String ? Boolean.parseBoolean((String) result) : (Boolean) result; } @@ -322,14 +341,15 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity @Override public String lookupAttributeString( - long deviceId, String attributeName, String defaultValue, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig) { + Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); return result != null ? (String) result : defaultValue; } @Override - public int lookupAttributeInteger(long deviceId, String attributeName, int defaultValue, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + public int lookupAttributeInteger( + long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig) { + Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); if (result != null) { return result instanceof String ? Integer.parseInt((String) result) : ((Number) result).intValue(); } @@ -338,8 +358,8 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity @Override public long lookupAttributeLong( - long deviceId, String attributeName, long defaultValue, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig) { + Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); if (result != null) { return result instanceof String ? Long.parseLong((String) result) : ((Number) result).longValue(); } @@ -347,15 +367,15 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity } public double lookupAttributeDouble( - long deviceId, String attributeName, double defaultValue, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig) { + Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); if (result != null) { return result instanceof String ? Double.parseDouble((String) result) : ((Number) result).doubleValue(); } return defaultValue; } - private Object lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { + private Object lookupAttribute(long deviceId, String attributeName, boolean lookupServer, boolean lookupConfig) { Object result = null; Device device = getById(deviceId); if (device != null) { @@ -375,13 +395,12 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity } } } - if (result == null) { - if (lookupConfig) { - result = Context.getConfig().getString(attributeName); - } else { - Server server = Context.getPermissionsManager().getServer(); - result = server.getAttributes().get(attributeName); - } + if (result == null && lookupServer) { + Server server = Context.getPermissionsManager().getServer(); + result = server.getAttributes().get(attributeName); + } + if (result == null && lookupConfig) { + result = Context.getConfig().getString(attributeName); } } return result; diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index 6228a0f75..af6a6ce71 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,18 +26,25 @@ public interface IdentityManager { Device getByUniqueId(String uniqueId) throws Exception; + String getDevicePassword(long id, String protocol, String defaultPassword); + Position getLastPosition(long deviceId); boolean isLatestPosition(Position position); - boolean lookupAttributeBoolean(long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig); + boolean lookupAttributeBoolean( + long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig); - String lookupAttributeString(long deviceId, String attributeName, String defaultValue, boolean lookupConfig); + String lookupAttributeString( + long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig); - int lookupAttributeInteger(long deviceId, String attributeName, int defaultValue, boolean lookupConfig); + int lookupAttributeInteger( + long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig); - long lookupAttributeLong(long deviceId, String attributeName, long defaultValue, boolean lookupConfig); + long lookupAttributeLong( + long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig); - double lookupAttributeDouble(long deviceId, String attributeName, double defaultValue, boolean lookupConfig); + double lookupAttributeDouble( + long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig); } diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index 6a0966d33..3cd7d144d 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -33,7 +33,7 @@ public class CopyAttributesHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { String attributesString = identityManager.lookupAttributeString( - position.getDeviceId(), "processing.copyAttributes", "", true); + position.getDeviceId(), "processing.copyAttributes", "", false, true); if (attributesString.isEmpty()) { attributesString = Position.KEY_DRIVER_UNIQUE_ID; } else { diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index dceaede01..7cd9153c1 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -130,7 +130,7 @@ public class FilterHandler extends BaseDataHandler { private boolean skipAttributes(Position position) { if (skipAttributes) { String attributesString = Context.getIdentityManager().lookupAttributeString( - position.getDeviceId(), "filter.skipAttributes", "", true); + position.getDeviceId(), "filter.skipAttributes", "", false, true); for (String attribute : attributesString.split("[ ,]")) { if (position.getAttributes().containsKey(attribute)) { return true; diff --git a/src/main/java/org/traccar/handler/GeolocationHandler.java b/src/main/java/org/traccar/handler/GeolocationHandler.java index c7b39e491..0e78322c8 100644 --- a/src/main/java/org/traccar/handler/GeolocationHandler.java +++ b/src/main/java/org/traccar/handler/GeolocationHandler.java @@ -65,7 +65,6 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter { position.setAltitude(0); position.setSpeed(0); position.setCourse(0); - position.set(Position.KEY_RSSI, 0); ctx.fireChannelRead(position); } diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java index 59de61bba..bc1426b86 100644 --- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java @@ -47,7 +47,7 @@ public class FuelDropEventHandler extends BaseEventHandler { } double fuelDropThreshold = identityManager - .lookupAttributeDouble(device.getId(), ATTRIBUTE_FUEL_DROP_THRESHOLD, 0, false); + .lookupAttributeDouble(device.getId(), ATTRIBUTE_FUEL_DROP_THRESHOLD, 0, true, false); if (fuelDropThreshold > 0) { Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 157bb64e0..e534df9de 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -120,7 +120,7 @@ public class OverspeedEventHandler extends BaseEventHandler { return null; } - double speedLimit = deviceManager.lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, false); + double speedLimit = deviceManager.lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, true, false); double geofenceSpeedLimit = 0; long overspeedGeofenceId = 0; diff --git a/src/main/java/org/traccar/helper/DateBuilder.java b/src/main/java/org/traccar/helper/DateBuilder.java index 6e1b779f0..9752f6977 100644 --- a/src/main/java/org/traccar/helper/DateBuilder.java +++ b/src/main/java/org/traccar/helper/DateBuilder.java @@ -69,7 +69,9 @@ public class DateBuilder { public DateBuilder setCurrentDate() { Calendar now = Calendar.getInstance(calendar.getTimeZone()); - return setYear(now.get(Calendar.YEAR)).setMonth(now.get(Calendar.MONTH)).setDay(now.get(Calendar.DAY_OF_MONTH)); + return setYear(now.get(Calendar.YEAR)) + .setMonth(now.get(Calendar.MONTH) + 1) + .setDay(now.get(Calendar.DAY_OF_MONTH)); } public DateBuilder setHour(int hour) { diff --git a/src/main/java/org/traccar/model/Network.java b/src/main/java/org/traccar/model/Network.java index 2d56950f1..4d67fc5d8 100644 --- a/src/main/java/org/traccar/model/Network.java +++ b/src/main/java/org/traccar/model/Network.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,10 @@ public class Network { addCellTower(cellTower); } + public Network(WifiAccessPoint wifiAccessPoint) { + addWifiAccessPoint(wifiAccessPoint); + } + private Integer homeMobileCountryCode; public Integer getHomeMobileCountryCode() { diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 6032dc588..2c0e22c9e 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -82,6 +82,9 @@ public class Position extends Message { public static final String KEY_BLOCKED = "blocked"; public static final String KEY_DOOR = "door"; public static final String KEY_AXLE_WEIGHT = "axleWeight"; + public static final String KEY_G_SENSOR = "gSensor"; + public static final String KEY_ICCID = "iccid"; + public static final String KEY_PHONE = "phone"; public static final String KEY_DTCS = "dtcs"; public static final String KEY_OBD_SPEED = "obdSpeed"; // knots diff --git a/src/main/java/org/traccar/protocol/AdmProtocol.java b/src/main/java/org/traccar/protocol/AdmProtocol.java index 08f932ceb..93b1e355a 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocol.java +++ b/src/main/java/org/traccar/protocol/AdmProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ public class AdmProtocol extends BaseProtocol { protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 1, -3, 0, true)); pipeline.addLast(new StringEncoder()); - pipeline.addLast(new AdmProtocolEncoder()); + pipeline.addLast(new AdmProtocolEncoder(AdmProtocol.this)); pipeline.addLast(new AdmProtocolDecoder(AdmProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java b/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java index e76bc2ddc..1c3dfc156 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * Copyright 2017 Anatoliy Golubev (darth.naihil@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,9 +18,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class AdmProtocolEncoder extends StringProtocolEncoder { + public AdmProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java b/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java index 57af5e366..3c43ddf2a 100644 --- a/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +17,11 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; -import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; -import org.traccar.model.CellTower; -import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; @@ -134,9 +130,11 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder { .number("xx") // checksum .compile(); - private Position decodeA(Channel channel, SocketAddress remoteAddress, String sentence) { + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - Parser parser = new Parser(PATTERN_A, sentence); + Parser parser = new Parser(PATTERN_A, (String) msg); if (!parser.matches()) { return null; } @@ -218,186 +216,4 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder { return position; } - private static final Pattern PATTERN_B_1 = new PatternBuilder() - .text("$") - .expression("[^,]+,") // header - .expression("[^,]+,") // client - .expression("[^,]+,") // firmware version - .expression(".{2},") // packet type - .number("d+,") // message id - .expression("[LH],") // status - .number("(d+),") // imei - .expression("[^,]+,") // registration number - .number("([01]),") // validity - .number("(dd)(dd)(dddd),") // date (ddmmyyyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(-?d+.d+),") // latitude - .expression("([NS]),") - .number("(-?d+.d+),") // longitude - .expression("([EW]),") - .number("(d+.d+),") // speed - .number("(d+),") // course - .number("(d+),") // satellites - .number("(-?d+.d+),") // altitude - .number("(d+.d+),") // pdop - .number("(d+.d+),") // hdop - .expression("[^,]+,") // operator - .number("([01]),") // ignition - .number("([01]),") // charge - .number("(d+.d+),") // power - .number("(d+.d+),") // battery - .number("([01]),") // emergency - .expression("[CO],") // tamper - .number("(d+),") // rssi - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(x+),") // lac - .number("(x+),") // cid - .number("(d+),(x+),(x+),") // cell 1 - .number("(d+),(x+),(x+),") // cell 2 - .number("(d+),(x+),(x+),") // cell 3 - .number("(d+),(x+),(x+),") // cell 4 - .number("([01])+,") // inputs - .number("([01])+,") // outputs - .number("d+,") // frame number - .number("(d+.d+),") // adc1 - .number("(d+.d+),") // adc2 - .number("d+,") // delta distance - .any() - .compile(); - - private static final Pattern PATTERN_B_2 = new PatternBuilder() - .text("$") - .expression("[^,]+,") // header - .expression("[^,]+,") // client - .expression("(.{3}),") // message type - .number("(d+),") // imei - .expression(".{2},") // packet type - .number("(dd)(dd)(dddd)") // date (ddmmyyyy) - .number("(dd)(dd)(dd),") // time (hhmmss) - .expression("([AV]),") // validity - .number("(-?d+.d+),") // latitude - .expression("([NS]),") - .number("(-?d+.d+),") // longitude - .expression("([EW]),") - .number("(-?d+.d+),") // altitude - .number("(d+.d+),") // speed - .any() - .compile(); - - private Position decodeB2(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_B_2, sentence); - if (!parser.matches()) { - return null; - } - - String type = parser.next(); - String id = parser.next(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setAltitude(parser.nextDouble()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - - if (type.equals("EMR") && channel != null) { - String password = Context.getIdentityManager().lookupAttributeString( - deviceSession.getDeviceId(), getProtocolName() + ".password", "aquila123", true); - channel.writeAndFlush(new NetworkMessage( - "#set$" + id + "@" + password + "#EMR_MODE:0*", remoteAddress)); - } - - return position; - } - - private Position decodeB1(Channel channel, SocketAddress remoteAddress, String sentence) { - - Parser parser = new Parser(PATTERN_B_1, sentence); - if (!parser.matches()) { - return null; - } - - String id = parser.next(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setValid(parser.nextInt() == 1); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextInt()); - - position.set(Position.KEY_SATELLITES, parser.nextInt()); - - position.setAltitude(parser.nextDouble()); - - position.set(Position.KEY_PDOP, parser.nextDouble()); - position.set(Position.KEY_HDOP, parser.nextDouble()); - position.set(Position.KEY_IGNITION, parser.nextInt() == 1); - position.set(Position.KEY_CHARGE, parser.nextInt() == 1); - position.set(Position.KEY_POWER, parser.nextDouble()); - position.set(Position.KEY_BATTERY, parser.nextDouble()); - - if (parser.nextInt() == 1) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } - - Network network = new Network(); - - int rssi = parser.nextInt(); - int mcc = parser.nextInt(); - int mnc = parser.nextInt(); - - network.addCellTower(CellTower.from(mcc, mnc, parser.nextHexInt(), parser.nextHexInt(), rssi)); - for (int i = 0; i < 4; i++) { - rssi = parser.nextInt(); - network.addCellTower(CellTower.from(mcc, mnc, parser.nextHexInt(), parser.nextHexInt(), rssi)); - } - - position.setNetwork(network); - - position.set(Position.KEY_INPUT, parser.nextBinInt()); - position.set(Position.KEY_OUTPUT, parser.nextBinInt()); - position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); - position.set(Position.PREFIX_ADC + 2, parser.nextDouble()); - - return position; - } - - private Position decodeB(Channel channel, SocketAddress remoteAddress, String sentence) { - if (sentence.contains("EMR") || sentence.contains("SEM")) { - return decodeB2(channel, remoteAddress, sentence); - } else { - return decodeB1(channel, remoteAddress, sentence); - } - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - if (sentence.startsWith("$$")) { - return decodeA(channel, remoteAddress, sentence); - } else { - return decodeB(channel, remoteAddress, sentence); - } - } - } diff --git a/src/main/java/org/traccar/protocol/AtrackProtocol.java b/src/main/java/org/traccar/protocol/AtrackProtocol.java index 8e5cfe9ff..429708b26 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,14 +29,14 @@ public class AtrackProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new AtrackFrameDecoder()); - pipeline.addLast(new AtrackProtocolEncoder()); + pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this)); pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new AtrackProtocolEncoder()); + pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this)); pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 71bb6791c..53f04234d 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,6 +84,10 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { this.custom = custom; } + public void setForm(String form) { + this.form = form; + } + private static void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) { if (channel != null) { ByteBuf response = Unpooled.buffer(12); @@ -156,7 +160,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_THROTTLE, Integer.parseInt(values[i])); break; case "ET": - position.set(Position.PREFIX_TEMP + 1, Integer.parseInt(values[i])); + position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[i])); break; case "FL": position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(values[i])); @@ -167,6 +171,36 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { case "AV1": position.set(Position.PREFIX_ADC + 1, Integer.parseInt(values[i])); break; + case "CD": + position.set(Position.KEY_ICCID, values[i]); + break; + case "EH": + position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(Integer.parseInt(values[i]) * 0.1)); + break; + case "IA": + position.set("intakeTemp", Integer.parseInt(values[i])); + break; + case "EL": + position.set(Position.KEY_ENGINE_LOAD, Integer.parseInt(values[i])); + break; + case "HA": + if (Integer.parseInt(values[i]) > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + } + break; + case "HB": + if (Integer.parseInt(values[i]) > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + } + break; + case "HC": + if (Integer.parseInt(values[i]) > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + } + break; + case "MT": + position.set(Position.KEY_MOTION, Integer.parseInt(values[i]) > 0); + break; default: break; } @@ -274,7 +308,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // pending code status break; case "CD": - readString(buf); // sim cid + position.set(Position.KEY_ICCID, readString(buf)); break; case "CM": buf.readLong(); // imsi diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java index 1e085cb26..d803ae391 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,11 +18,16 @@ package org.traccar.protocol; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.charset.StandardCharsets; public class AtrackProtocolEncoder extends BaseProtocolEncoder { + public AtrackProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java b/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java index 16a31162a..37836ad5f 100644 --- a/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,17 +48,19 @@ public class AvemaProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // event .number("(d+.d+),") // odometer .number("(d+),") // input - .number("(d+.d+)V,") // adc 1 - .number("(d+.d+)V,") // adc 2 + .number("(d+.d+)V?,") // adc 1 + .number("(d+.d+)V?,") // adc 2 .number("(d+),") // output .number("(d),") // roaming .number("(d+),") // rssi .number("d,") // communication system - .number("(ddd)") // mcc - .number("(dd),") // mnc + .number("(ddd)-?") // mcc + .number("(d+),") // mnc .number("(x+),") // lac .number("(x+),") // cid + .number("(d+.d+),").optional() // battery .number("([^,]+)?") // rfid + .any() .compile(); @Override @@ -99,6 +101,7 @@ public class AvemaProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(new Network(CellTower.from( parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt(), rssi))); + position.set(Position.KEY_BATTERY, parser.nextDouble()); position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); return position; diff --git a/src/main/java/org/traccar/protocol/BceProtocol.java b/src/main/java/org/traccar/protocol/BceProtocol.java index 6453a05a9..c5e1dd04c 100644 --- a/src/main/java/org/traccar/protocol/BceProtocol.java +++ b/src/main/java/org/traccar/protocol/BceProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ public class BceProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new BceFrameDecoder()); - pipeline.addLast(new BceProtocolEncoder()); + pipeline.addLast(new BceProtocolEncoder(BceProtocol.this)); pipeline.addLast(new BceProtocolDecoder(BceProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java index ad7271f2f..30f9bb1f3 100644 --- a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java @@ -29,6 +29,7 @@ import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -106,31 +107,31 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // acceleration pedal } if (BitUtil.check(mask, 2)) { - buf.readUnsignedIntLE(); // total fuel used + position.set(Position.KEY_FUEL_USED, buf.readUnsignedIntLE()); } if (BitUtil.check(mask, 3)) { - buf.readUnsignedByte(); // fuel level + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); } if (BitUtil.check(mask, 4)) { - buf.readUnsignedShortLE(); // engine speed + position.set(Position.KEY_RPM, buf.readUnsignedShortLE()); } if (BitUtil.check(mask, 5)) { - buf.readUnsignedIntLE(); // total hours + position.set(Position.KEY_HOURS, buf.readUnsignedIntLE()); } if (BitUtil.check(mask, 6)) { - buf.readUnsignedIntLE(); // total distance + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); } if (BitUtil.check(mask, 7)) { - buf.readUnsignedByte(); // engine coolant + position.set(Position.KEY_COOLANT_TEMP, (int) buf.readByte()); } if (BitUtil.check(mask, 8)) { - buf.readUnsignedByte(); // fuel level 2 + position.set("fuel2", buf.readUnsignedByte()); } if (BitUtil.check(mask, 9)) { - buf.readUnsignedByte(); // engine load + position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); } if (BitUtil.check(mask, 10)) { - buf.readUnsignedShortLE(); // service distance + position.set(Position.KEY_ODOMETER_SERVICE, buf.readUnsignedShortLE()); } if (BitUtil.check(mask, 11)) { buf.skipBytes(8); // sensors @@ -142,7 +143,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(8); // trailer id } if (BitUtil.check(mask, 14)) { - buf.readUnsignedShortLE(); // fuel rate + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShortLE()); } } @@ -152,10 +153,10 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShortLE(); // fuel economy } if (BitUtil.check(mask, 1)) { - buf.readUnsignedIntLE(); // fuel consumption + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedIntLE()); } if (BitUtil.check(mask, 2)) { - buf.readUnsignedMediumLE(); // axle weight + position.set(Position.KEY_AXLE_WEIGHT, buf.readUnsignedMediumLE()); } if (BitUtil.check(mask, 3)) { buf.readUnsignedByte(); // mil status @@ -169,6 +170,70 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(mask, 6)) { position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readLongLE())); } + if (BitUtil.check(mask, 7)) { + buf.readUnsignedShortLE(); // dallas temperature + } + if (BitUtil.check(mask, 8)) { + buf.readUnsignedShortLE(); // dallas humidity + } + if (BitUtil.check(mask, 9)) { + buf.skipBytes(6); // lls group 1 + } + if (BitUtil.check(mask, 10)) { + buf.skipBytes(6); // lls group 2 + } + if (BitUtil.check(mask, 11)) { + buf.skipBytes(21); // j1979 group 1 + } + if (BitUtil.check(mask, 12)) { + buf.skipBytes(20); // j1979 dtc + } + if (BitUtil.check(mask, 13)) { + buf.skipBytes(9); // j1708 group 1 + } + if (BitUtil.check(mask, 14)) { + buf.skipBytes(21); // driving quality + } + } + + private void decodeMask4(ByteBuf buf, int mask, Position position) { + + if (BitUtil.check(mask, 0)) { + buf.readUnsignedIntLE(); + } + if (BitUtil.check(mask, 1)) { + buf.skipBytes(30); // lls group 3 + } + if (BitUtil.check(mask, 2)) { + buf.readUnsignedIntLE(); // instant fuel consumption + } + if (BitUtil.check(mask, 3)) { + buf.skipBytes(10); // axle weight group + } + if (BitUtil.check(mask, 4)) { + buf.readUnsignedByte(); + } + if (BitUtil.check(mask, 5)) { + buf.readUnsignedShortLE(); + } + if (BitUtil.check(mask, 6)) { + buf.readUnsignedByte(); // maximum acceleration + buf.readUnsignedByte(); // maximum deceleration + buf.readUnsignedByte(); // maximum cornering + } + if (BitUtil.check(mask, 7)) { + buf.skipBytes(16); + } + if (BitUtil.check(mask, 8)) { + buf.skipBytes(40); // temperature sensors + } + if (BitUtil.check(mask, 9)) { + position.set("driver1", buf.readCharSequence(16, StandardCharsets.US_ASCII).toString().trim()); + position.set("driver2", buf.readCharSequence(16, StandardCharsets.US_ASCII).toString().trim()); + } + if (BitUtil.check(mask, 10)) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + } } @Override @@ -230,6 +295,11 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { mask = masks.get(2); decodeMask3(buf, mask, position); } + + if (masks.size() >= 4) { + mask = masks.get(3); + decodeMask4(buf, mask, position); + } } buf.readerIndex(structEnd); diff --git a/src/main/java/org/traccar/protocol/BceProtocolEncoder.java b/src/main/java/org/traccar/protocol/BceProtocolEncoder.java index 1bbf3db12..53ac51581 100644 --- a/src/main/java/org/traccar/protocol/BceProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/BceProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,14 @@ import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.model.Command; +import org.traccar.Protocol; public class BceProtocolEncoder extends BaseProtocolEncoder { + public BceProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java b/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java index 31416d7f1..dad0ae774 100644 --- a/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -153,7 +153,7 @@ public class CalAmpProtocolDecoder extends BaseProtocolDecoder { int content = buf.readUnsignedByte(); if (BitUtil.check(content, 0)) { - String id = ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())); + String id = ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())).replace("f", ""); getDeviceSession(channel, remoteAddress, id); } diff --git a/src/main/java/org/traccar/protocol/CarcellProtocol.java b/src/main/java/org/traccar/protocol/CarcellProtocol.java index 0c305efcb..f08ab3bd9 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocol.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ public class CarcellProtocol extends BaseProtocol { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new CarcellProtocolEncoder()); + pipeline.addLast(new CarcellProtocolEncoder(CarcellProtocol.this)); pipeline.addLast(new CarcellProtocolDecoder(CarcellProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java index 344b2f1ea..ec640ba71 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java @@ -155,7 +155,7 @@ public class CarcellProtocolDecoder extends BaseProtocolDecoder { Double mainVoltage = parser.nextDouble(0) / 100d; position.set(Position.KEY_POWER, mainVoltage); - position.set("iccid", parser.next()); + position.set(Position.KEY_ICCID, parser.next()); } return position; diff --git a/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java b/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java index e8f0081a0..083fe9a9e 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class CarcellProtocolEncoder extends StringProtocolEncoder { + public CarcellProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/CastelProtocol.java b/src/main/java/org/traccar/protocol/CastelProtocol.java index 9b854afc3..44c52d68f 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocol.java +++ b/src/main/java/org/traccar/protocol/CastelProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,14 +32,14 @@ public class CastelProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); - pipeline.addLast(new CastelProtocolEncoder()); + pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this)); pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CastelProtocolEncoder()); + pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this)); pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index 0541adf6f..03e4b25fd 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,6 +84,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { public static final short MSG_SC_HEARTBEAT_RESPONSE = (short) 0x9003; public static final short MSG_SC_GPS = 0x4001; public static final short MSG_SC_PID_DATA = 0x4002; + public static final short MSG_SC_G_SENSOR = 0x4003; public static final short MSG_SC_SUPPORTED_PID = 0x4004; public static final short MSG_SC_OBD_DATA = 0x4005; public static final short MSG_SC_DTCS_PASSENGER = 0x4006; @@ -290,152 +291,179 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, ByteBuf buf, int version, ByteBuf id, short type, DeviceSession deviceSession) { - if (type == MSG_SC_HEARTBEAT) { - - sendResponse(channel, remoteAddress, version, id, MSG_SC_HEARTBEAT_RESPONSE, null); - - } else if (type == MSG_SC_LOGIN || type == MSG_SC_LOGOUT || type == MSG_SC_GPS - || type == MSG_SC_ALARM || type == MSG_SC_CURRENT_LOCATION || type == MSG_SC_FUEL) { - - if (type == MSG_SC_LOGIN) { - ByteBuf response = Unpooled.buffer(10); - response.writeIntLE(0xFFFFFFFF); - response.writeShortLE(0); - response.writeIntLE((int) (System.currentTimeMillis() / 1000)); - sendResponse(channel, remoteAddress, version, id, MSG_SC_LOGIN_RESPONSE, response); - } - - if (type == MSG_SC_GPS) { - buf.readUnsignedByte(); // historical - } else if (type == MSG_SC_ALARM) { - buf.readUnsignedIntLE(); // alarm - } else if (type == MSG_SC_CURRENT_LOCATION) { - buf.readUnsignedShortLE(); - } - - buf.readUnsignedIntLE(); // ACC ON time - buf.readUnsignedIntLE(); // UTC time - long odometer = buf.readUnsignedIntLE(); - long tripOdometer = buf.readUnsignedIntLE(); - long fuelConsumption = buf.readUnsignedIntLE(); - buf.readUnsignedShortLE(); // current fuel consumption - long status = buf.readUnsignedIntLE(); - buf.skipBytes(8); - - int count = buf.readUnsignedByte(); + Position position; + int count; + + switch (type) { + + case MSG_SC_HEARTBEAT: + sendResponse(channel, remoteAddress, version, id, MSG_SC_HEARTBEAT_RESPONSE, null); + return null; + + case MSG_SC_LOGIN: + case MSG_SC_LOGOUT: + case MSG_SC_GPS: + case MSG_SC_ALARM: + case MSG_SC_CURRENT_LOCATION: + case MSG_SC_FUEL: + if (type == MSG_SC_LOGIN) { + ByteBuf response = Unpooled.buffer(10); + response.writeIntLE(0xFFFFFFFF); + response.writeShortLE(0); + response.writeIntLE((int) (System.currentTimeMillis() / 1000)); + sendResponse(channel, remoteAddress, version, id, MSG_SC_LOGIN_RESPONSE, response); + } - List<Position> positions = new LinkedList<>(); + if (type == MSG_SC_GPS) { + buf.readUnsignedByte(); // historical + } else if (type == MSG_SC_ALARM) { + buf.readUnsignedIntLE(); // alarm + } else if (type == MSG_SC_CURRENT_LOCATION) { + buf.readUnsignedShortLE(); + } - for (int i = 0; i < count; i++) { - Position position = readPosition(deviceSession, buf); - position.set(Position.KEY_ODOMETER, odometer); - position.set(Position.KEY_ODOMETER_TRIP, tripOdometer); - position.set(Position.KEY_FUEL_CONSUMPTION, fuelConsumption); - position.set(Position.KEY_STATUS, status); - positions.add(position); - } + buf.readUnsignedIntLE(); // ACC ON time + buf.readUnsignedIntLE(); // UTC time + long odometer = buf.readUnsignedIntLE(); + long tripOdometer = buf.readUnsignedIntLE(); + long fuelConsumption = buf.readUnsignedIntLE(); + buf.readUnsignedShortLE(); // current fuel consumption + long status = buf.readUnsignedIntLE(); + buf.skipBytes(8); + + count = buf.readUnsignedByte(); + + List<Position> positions = new LinkedList<>(); + + for (int i = 0; i < count; i++) { + position = readPosition(deviceSession, buf); + position.set(Position.KEY_ODOMETER, odometer); + position.set(Position.KEY_ODOMETER_TRIP, tripOdometer); + position.set(Position.KEY_FUEL_CONSUMPTION, fuelConsumption); + position.set(Position.KEY_STATUS, status); + positions.add(position); + } - if (type == MSG_SC_ALARM) { - int alarmCount = buf.readUnsignedByte(); - for (int i = 0; i < alarmCount; i++) { - if (buf.readUnsignedByte() != 0) { - int alarm = buf.readUnsignedByte(); - for (Position position : positions) { - decodeAlarm(position, alarm); + if (type == MSG_SC_ALARM) { + int alarmCount = buf.readUnsignedByte(); + for (int i = 0; i < alarmCount; i++) { + if (buf.readUnsignedByte() != 0) { + int alarm = buf.readUnsignedByte(); + for (Position p : positions) { + decodeAlarm(p, alarm); + } + buf.readUnsignedShortLE(); // description + buf.readUnsignedShortLE(); // threshold } - buf.readUnsignedShortLE(); // description - buf.readUnsignedShortLE(); // threshold + } + } else if (type == MSG_SC_FUEL) { + for (Position p : positions) { + p.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); } } - } else if (type == MSG_SC_FUEL) { - for (Position position : positions) { - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE()); - } - } - if (!positions.isEmpty()) { - return positions; - } + return positions.isEmpty() ? null : positions; - } else if (type == MSG_SC_GPS_SLEEP) { + case MSG_SC_GPS_SLEEP: + buf.readUnsignedIntLE(); // device time + return readPosition(deviceSession, buf); - buf.readUnsignedIntLE(); // device time + case MSG_SC_AGPS_REQUEST: + return readPosition(deviceSession, buf); - return readPosition(deviceSession, buf); + case MSG_SC_PID_DATA: + position = createPosition(deviceSession); - } else if (type == MSG_SC_AGPS_REQUEST) { + decodeStat(position, buf); - return readPosition(deviceSession, buf); + buf.readUnsignedShortLE(); // sample rate + decodeObd(position, buf, true); - } else if (type == MSG_SC_PID_DATA) { + return position; - Position position = createPosition(deviceSession); + case MSG_SC_G_SENSOR: + position = createPosition(deviceSession); - decodeStat(position, buf); + decodeStat(position, buf); - buf.readUnsignedShortLE(); // sample rate - decodeObd(position, buf, true); + buf.readUnsignedShortLE(); // sample rate - return position; + count = buf.readUnsignedByte(); - } else if (type == MSG_SC_DTCS_PASSENGER) { + StringBuilder data = new StringBuilder("["); + for (int i = 0; i < count; i++) { + if (i > 0) { + data.append(","); + } + data.append("["); + data.append(buf.readShortLE() * 0.015625); + data.append(","); + data.append(buf.readShortLE() * 0.015625); + data.append(","); + data.append(buf.readShortLE() * 0.015625); + data.append("]"); + } + data.append("]"); - Position position = createPosition(deviceSession); + position.set(Position.KEY_G_SENSOR, data.toString()); - decodeStat(position, buf); + return position; - buf.readUnsignedByte(); // flag - position.add(ObdDecoder.decodeCodes(ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())))); + case MSG_SC_DTCS_PASSENGER: + position = createPosition(deviceSession); - return position; + decodeStat(position, buf); - } else if (type == MSG_SC_OBD_DATA) { + buf.readUnsignedByte(); // flag + position.add(ObdDecoder.decodeCodes(ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())))); - Position position = createPosition(deviceSession); + return position; - decodeStat(position, buf); + case MSG_SC_OBD_DATA: + position = createPosition(deviceSession); - buf.readUnsignedByte(); // flag - decodeObd(position, buf, false); + decodeStat(position, buf); - return position; + buf.readUnsignedByte(); // flag + decodeObd(position, buf, false); - } else if (type == MSG_SC_CELL) { + return position; - Position position = createPosition(deviceSession); + case MSG_SC_CELL: + position = createPosition(deviceSession); - decodeStat(position, buf); + decodeStat(position, buf); - position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); + position.setNetwork(new Network( + CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); - return position; + return position; - } else if (type == MSG_SC_QUERY_RESPONSE) { + case MSG_SC_QUERY_RESPONSE: + position = createPosition(deviceSession); - Position position = createPosition(deviceSession); + buf.readUnsignedShortLE(); // index + buf.readUnsignedByte(); // response count + buf.readUnsignedByte(); // response index - buf.readUnsignedShortLE(); // index - buf.readUnsignedByte(); // response count - buf.readUnsignedByte(); // response index + int failureCount = buf.readUnsignedByte(); + for (int i = 0; i < failureCount; i++) { + buf.readUnsignedShortLE(); // tag + } - int failureCount = buf.readUnsignedByte(); - for (int i = 0; i < failureCount; i++) { - buf.readUnsignedShortLE(); // tag - } + int successCount = buf.readUnsignedByte(); + for (int i = 0; i < successCount; i++) { + buf.readUnsignedShortLE(); // tag + position.set(Position.KEY_RESULT, + buf.readSlice(buf.readUnsignedShortLE()).toString(StandardCharsets.US_ASCII)); + } - int successCount = buf.readUnsignedByte(); - for (int i = 0; i < successCount; i++) { - buf.readUnsignedShortLE(); // tag - position.set(Position.KEY_RESULT, - buf.readSlice(buf.readUnsignedShortLE()).toString(StandardCharsets.US_ASCII)); - } + return position; - return position; + default: + return null; } - - return null; } private Object decodeCc( diff --git a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java index e1f78e7c1..dc694da28 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,16 @@ import org.traccar.BaseProtocolEncoder; import org.traccar.Context; import org.traccar.helper.Checksum; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.charset.StandardCharsets; public class CastelProtocolEncoder extends BaseProtocolEncoder { + public CastelProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeContent(long deviceId, short type, ByteBuf content) { ByteBuf buf = Unpooled.buffer(0); diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocol.java b/src/main/java/org/traccar/protocol/CellocatorProtocol.java index a52170dc9..d910877cf 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocol.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,14 +29,14 @@ public class CellocatorProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new CellocatorFrameDecoder()); - pipeline.addLast(new CellocatorProtocolEncoder()); + pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this)); pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CellocatorProtocolEncoder()); + pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this)); pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java index 14d14f4b6..aa13a0aa2 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -43,29 +43,52 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_SERVER_ACKNOWLEDGE = 4; - private byte commandCount; + public static ByteBuf encodeContent(int type, int uniqueId, int packetNumber, ByteBuf content) { + + ByteBuf buf = Unpooled.buffer(); + buf.writeByte('M'); + buf.writeByte('C'); + buf.writeByte('G'); + buf.writeByte('P'); + buf.writeByte(type); + buf.writeIntLE(uniqueId); + buf.writeByte(packetNumber); + buf.writeIntLE(0); // authentication code + buf.writeBytes(content); + + byte checksum = 0; + for (int i = 4; i < buf.writerIndex(); i++) { + checksum += buf.getByte(i); + } + buf.writeByte(checksum); + + return buf; + } private void sendResponse(Channel channel, SocketAddress remoteAddress, long deviceId, byte packetNumber) { if (channel != null) { - ByteBuf reply = Unpooled.buffer(28); - reply.writeByte('M'); - reply.writeByte('C'); - reply.writeByte('G'); - reply.writeByte('P'); - reply.writeByte(MSG_SERVER_ACKNOWLEDGE); - reply.writeIntLE((int) deviceId); - reply.writeByte(commandCount++); - reply.writeIntLE(0); // authentication code - reply.writeByte(0); - reply.writeByte(packetNumber); - reply.writeZero(11); - - byte checksum = 0; - for (int i = 4; i < 27; i++) { - checksum += reply.getByte(i); - } - reply.writeByte(checksum); + ByteBuf content = Unpooled.buffer(); + content.writeByte(0); + content.writeByte(packetNumber); + content.writeZero(11); + ByteBuf reply = encodeContent(MSG_SERVER_ACKNOWLEDGE, (int) deviceId, packetNumber, content); + channel.writeAndFlush(new NetworkMessage(reply, remoteAddress)); + } + } + + private void sendModuleResponse(Channel channel, SocketAddress remoteAddress, long deviceId, byte packetNumber) { + if (channel != null) { + ByteBuf content = Unpooled.buffer(); + content.writeByte(0x80); + content.writeShortLE(10); // modules length + content.writeIntLE(0); // reserved + content.writeByte(9); // ack module type + content.writeShortLE(3); // module length + content.writeByte(0); // ack + content.writeShortLE(0); // reserved + + ByteBuf reply = encodeContent(MSG_CLIENT_MODULAR_EXT, (int) deviceId, packetNumber, content); channel.writeAndFlush(new NetworkMessage(reply, remoteAddress)); } } @@ -225,7 +248,11 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { } byte packetNumber = buf.readByte(); - sendResponse(channel, remoteAddress, deviceUniqueId, packetNumber); + if (type == MSG_CLIENT_MODULAR_EXT) { + sendModuleResponse(channel, remoteAddress, deviceUniqueId, packetNumber); + } else { + sendResponse(channel, remoteAddress, deviceUniqueId, packetNumber); + } if (type == MSG_CLIENT_STATUS) { return decodeStatus(buf, deviceSession, alternative); diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java index 0382dbbc7..76fa67686 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,27 +19,26 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class CellocatorProtocolEncoder extends BaseProtocolEncoder { - private ByteBuf encodeContent(long deviceId, int command, int data1, int data2) { + public CellocatorProtocolEncoder(Protocol protocol) { + super(protocol); + } + + public static ByteBuf encodeContent(int type, int uniqueId, int packetNumber, ByteBuf content) { - ByteBuf buf = Unpooled.buffer(0); + ByteBuf buf = Unpooled.buffer(); buf.writeByte('M'); buf.writeByte('C'); buf.writeByte('G'); buf.writeByte('P'); - buf.writeByte(0); - buf.writeIntLE(Integer.parseInt(getUniqueId(deviceId))); - buf.writeByte(0); // command numerator + buf.writeByte(type); + buf.writeIntLE(uniqueId); + buf.writeByte(packetNumber); buf.writeIntLE(0); // authentication code - buf.writeByte(command); - buf.writeByte(command); - buf.writeByte(data1); - buf.writeByte(data1); - buf.writeByte(data2); - buf.writeByte(data2); - buf.writeIntLE(0); // command specific data + buf.writeBytes(content); byte checksum = 0; for (int i = 4; i < buf.writerIndex(); i++) { @@ -50,6 +49,23 @@ public class CellocatorProtocolEncoder extends BaseProtocolEncoder { return buf; } + private ByteBuf encodeCommand(long deviceId, int command, int data1, int data2) { + + ByteBuf content = Unpooled.buffer(); + content.writeByte(command); + content.writeByte(command); + content.writeByte(data1); + content.writeByte(data1); + content.writeByte(data2); + content.writeByte(data2); + content.writeIntLE(0); // command specific data + + ByteBuf buf = encodeContent(0, Integer.parseInt(getUniqueId(deviceId)), 0, content); + content.release(); + + return buf; + } + @Override protected Object encodeCommand(Command command) { @@ -57,7 +73,7 @@ public class CellocatorProtocolEncoder extends BaseProtocolEncoder { case Command.TYPE_OUTPUT_CONTROL: int data = Integer.parseInt(command.getString(Command.KEY_DATA)) << 4 + command.getInteger(Command.KEY_INDEX); - return encodeContent(command.getDeviceId(), 0x03, data, 0); + return encodeCommand(command.getDeviceId(), 0x03, data, 0); default: return null; } diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocol.java b/src/main/java/org/traccar/protocol/CityeasyProtocol.java index f4b49c9ff..8ab4ce93a 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocol.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ public class CityeasyProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); - pipeline.addLast(new CityeasyProtocolEncoder()); + pipeline.addLast(new CityeasyProtocolEncoder(CityeasyProtocol.this)); pipeline.addLast(new CityeasyProtocolDecoder(CityeasyProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java b/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java index 350fdf0ab..934105862 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,9 +22,14 @@ import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.model.Command; +import org.traccar.Protocol; public class CityeasyProtocolEncoder extends BaseProtocolEncoder { + public CityeasyProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeContent(int type, ByteBuf content) { ByteBuf buf = Unpooled.buffer(); diff --git a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java index c49f06d65..58a5a88e3 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -208,6 +208,7 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { position.set("solarPower", buf.readUnsignedShortLE() * 0.001); break; default: + buf.readUnsignedShortLE(); // other break; } } diff --git a/src/main/java/org/traccar/protocol/EelinkProtocol.java b/src/main/java/org/traccar/protocol/EelinkProtocol.java index de4ea971b..8a055d643 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocol.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,14 +34,14 @@ public class EelinkProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); - pipeline.addLast(new EelinkProtocolEncoder(false)); + pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, false)); pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new EelinkProtocolEncoder(true)); + pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, true)); pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index a6fd94b83..41d76f37f 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -412,7 +412,8 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { return decodeNew(deviceSession, buf, type, index); - } else if (type == MSG_HEARTBEAT && buf.readableBytes() >= 2) { + } else if (type == MSG_HEARTBEAT && buf.readableBytes() >= 2 + || type == MSG_OBD && buf.readableBytes() == 4) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java index 8f33441fb..3673c35b3 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.DataConverter; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; @@ -28,7 +29,8 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder { private boolean connectionless; - public EelinkProtocolEncoder(boolean connectionless) { + public EelinkProtocolEncoder(Protocol protocol, boolean connectionless) { + super(protocol); this.connectionless = connectionless; } diff --git a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java index b9fcb2f44..9f0baf6b2 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,8 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + private boolean useObjectIdAsDeviceId = true; + public static final int PT_RESPONSE = 0; public static final int PT_APPDATA = 1; public static final int PT_SIGNED_APPDATA = 2; @@ -68,7 +70,7 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_ABS_CNTR_DATA = 25; public static final int MSG_ABS_LOOPIN_DATA = 26; public static final int MSG_LIQUID_LEVEL_SENSOR = 27; - public static final int MSG_PASSENGERS_COUNTERS = 28; + public static final int MSG_PASSENGERS_COUNTERS = 28; private int packetId; @@ -121,11 +123,18 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; + List<Position> positions = new LinkedList<>(); + + short headerLength = buf.getUnsignedByte(buf.readerIndex() + 3); int index = buf.getUnsignedShort(buf.readerIndex() + 5 + 2); - buf.skipBytes(buf.getUnsignedByte(buf.readerIndex() + 3)); + short packetType = buf.getUnsignedByte(buf.readerIndex() + 5 + 2 + 2); + buf.skipBytes(headerLength); - List<Position> positions = new LinkedList<>(); + if (packetType == PT_RESPONSE) { + return null; + } + long objectId = 0L; while (buf.readableBytes() > 2) { int length = buf.readUnsignedShortLE(); @@ -133,7 +142,7 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { int recordFlags = buf.readUnsignedByte(); if (BitUtil.check(recordFlags, 0)) { - buf.readUnsignedIntLE(); // object id + objectId = buf.readUnsignedIntLE(); } if (BitUtil.check(recordFlags, 1)) { @@ -164,6 +173,7 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { int end = buf.readUnsignedShortLE() + buf.readerIndex(); if (type == MSG_TERM_IDENTITY) { + useObjectIdAsDeviceId = false; buf.readUnsignedIntLE(); // object id int flags = buf.readUnsignedByte(); @@ -254,8 +264,16 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { buf.readerIndex(end); } - if (serviceType == SERVICE_TELEDATA && deviceSession != null) { - positions.add(position); + if (serviceType == SERVICE_TELEDATA && position.getValid()) { + if (useObjectIdAsDeviceId && objectId != 0L) { + deviceSession = getDeviceSession(channel, remoteAddress, true, String.valueOf(objectId)); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + } + } + if (deviceSession != null) { + positions.add(position); + } } } diff --git a/src/main/java/org/traccar/protocol/EnforaProtocol.java b/src/main/java/org/traccar/protocol/EnforaProtocol.java index f78e4b377..e462ab322 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocol.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocol.java @@ -32,14 +32,14 @@ public class EnforaProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, -2, 2)); - pipeline.addLast(new EnforaProtocolEncoder()); + pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this)); pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new EnforaProtocolEncoder()); + pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this)); pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java b/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java index a46e6367d..8cc24dc0f 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * Copyright 2017 Jose Castellanos * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,11 +20,16 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.charset.StandardCharsets; public class EnforaProtocolEncoder extends StringProtocolEncoder { + public EnforaProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeContent(String content) { ByteBuf buf = Unpooled.buffer(); diff --git a/src/main/java/org/traccar/protocol/EsealProtocol.java b/src/main/java/org/traccar/protocol/EsealProtocol.java index 7a27c617d..fc1d342e1 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocol.java +++ b/src/main/java/org/traccar/protocol/EsealProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ public class EsealProtocol extends BaseProtocol { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new EsealProtocolEncoder()); + pipeline.addLast(new EsealProtocolEncoder(EsealProtocol.this)); pipeline.addLast(new EsealProtocolDecoder(EsealProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java b/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java index b9bcc5b0a..6ee305ed8 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class EsealProtocolEncoder extends StringProtocolEncoder { + public EsealProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocol.java b/src/main/java/org/traccar/protocol/FifotrackProtocol.java index d1c3cf695..4a0a12ed3 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocol.java @@ -32,7 +32,7 @@ public class FifotrackProtocol extends BaseProtocol { protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new FifotrackFrameDecoder()); pipeline.addLast(new StringEncoder()); - pipeline.addLast(new FifotrackProtocolEncoder()); + pipeline.addLast(new FifotrackProtocolEncoder(FifotrackProtocol.this)); pipeline.addLast(new FifotrackProtocolDecoder(FifotrackProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 2e728a918..40e146e0b 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -60,7 +60,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { .number("(-?d+),") // altitude .number("(d+),") // odometer .number("d+,") // runtime - .number("(xxxx),") // status + .number("(x{4,8}),") // status .number("(x+)?,") // input .number("(x+)?,") // output .number("(d+)|") // mcc @@ -69,7 +69,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { .number("(x+),") // cid .number("([x|]+)") // adc .expression(",([^,]+)") // rfid - .expression(",([^*]+)").optional(2) // sensors + .expression(",([^*]*)").optional(2) // sensors .any() .compile(); @@ -105,6 +105,24 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { } } + private String decodeAlarm(Integer alarm) { + if (alarm != null) { + switch (alarm) { + case 2: + return Position.ALARM_SOS; + case 14: + return Position.ALARM_LOW_POWER; + case 15: + return Position.ALARM_POWER_CUT; + case 16: + return Position.ALARM_POWER_RESTORED; + default: + return null; + } + } + return null; + } + private Object decodeLocation( Channel channel, SocketAddress remoteAddress, String sentence) { @@ -121,35 +139,33 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.set(Position.KEY_ALARM, parser.next()); + position.set(Position.KEY_ALARM, decodeAlarm(parser.nextInt())); position.setTime(parser.nextDateTime()); position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextDouble(0)); - position.setLongitude(parser.nextDouble(0)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt(0))); - position.setCourse(parser.nextInt(0)); - position.setAltitude(parser.nextInt(0)); - - position.set(Position.KEY_ODOMETER, parser.nextLong(0)); - position.set(Position.KEY_STATUS, parser.nextHexInt(0)); - if (parser.hasNext()) { - position.set(Position.KEY_INPUT, parser.nextHexInt(0)); - } - if (parser.hasNext()) { - position.set(Position.KEY_OUTPUT, parser.nextHexInt(0)); - } + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + position.setCourse(parser.nextInt()); + position.setAltitude(parser.nextInt()); + + position.set(Position.KEY_ODOMETER, parser.nextLong()); + position.set(Position.KEY_STATUS, parser.nextHexLong()); + position.set(Position.KEY_INPUT, parser.nextHexInt()); + position.set(Position.KEY_OUTPUT, parser.nextHexInt()); position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt()))); String[] adc = parser.next().split("\\|"); for (int i = 0; i < adc.length; i++) { position.set(Position.PREFIX_ADC + (i + 1), Integer.parseInt(adc[i], 16)); } - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); + if (parser.hasNext()) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(parser.nextHexInt())); + } if (parser.hasNext()) { String[] sensors = parser.next().split("\\|"); diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java index ff0a2e56e..a4e69b47b 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java @@ -18,9 +18,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.model.Command; +import org.traccar.Protocol; public class FifotrackProtocolEncoder extends StringProtocolEncoder { + public FifotrackProtocolEncoder(Protocol protocol) { + super(protocol); + } + private Object formatCommand(Command command, String content) { String uniqueId = getUniqueId(command.getDeviceId()); int length = 1 + uniqueId.length() + 3 + content.length(); diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 86da3943e..7405fb6ef 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.Protocol; +import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import javax.json.Json; @@ -102,7 +103,7 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { position.setLongitude(((JsonNumber) value).doubleValue()); return true; case "position.speed": - position.setSpeed(((JsonNumber) value).doubleValue()); + position.setSpeed(UnitsConverter.knotsFromKph(((JsonNumber) value).doubleValue())); return true; case "position.direction": position.setCourse(((JsonNumber) value).doubleValue()); diff --git a/src/main/java/org/traccar/protocol/GalileoProtocol.java b/src/main/java/org/traccar/protocol/GalileoProtocol.java index 9b7fe1a4b..a1570c9b0 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocol.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ public class GalileoProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new GalileoFrameDecoder()); - pipeline.addLast(new GalileoProtocolEncoder()); + pipeline.addLast(new GalileoProtocolEncoder(GalileoProtocol.this)); pipeline.addLast(new GalileoProtocolDecoder(GalileoProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index 5b843324c..dfaedd695 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -318,7 +318,9 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // part number photo.writeBytes(buf, length - 1); - } else { + sendResponse(channel, 0x07, buf.readUnsignedShortLE()); + + } else if (photo != null) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); @@ -334,8 +336,6 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } - sendResponse(channel, 0x07, buf.readUnsignedShortLE()); - return position; } diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java index 3b2145e74..cd068b251 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +20,16 @@ import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.charset.StandardCharsets; public class GalileoProtocolEncoder extends BaseProtocolEncoder { + public GalileoProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeText(String uniqueId, String text) { ByteBuf buf = Unpooled.buffer(256); diff --git a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java index 31500bae6..043839be9 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -120,8 +120,10 @@ public class GatorProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_STATUS, buf.readUnsignedByte()); position.set("key", buf.readUnsignedByte()); - position.set("oil", buf.readUnsignedShort() / 10.0); - position.set(Position.KEY_POWER, buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); return position; diff --git a/src/main/java/org/traccar/protocol/Gl200Protocol.java b/src/main/java/org/traccar/protocol/Gl200Protocol.java index c5343dae0..e2d0c6d2a 100644 --- a/src/main/java/org/traccar/protocol/Gl200Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl200Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ public class Gl200Protocol extends BaseProtocol { protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new Gl200FrameDecoder()); pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Gl200ProtocolEncoder()); + pipeline.addLast(new Gl200ProtocolEncoder(Gl200Protocol.this)); pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); @@ -44,7 +44,7 @@ public class Gl200Protocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Gl200ProtocolEncoder()); + pipeline.addLast(new Gl200ProtocolEncoder(Gl200Protocol.this)); pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java index 285106c67..32307446b 100644 --- a/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class Gl200ProtocolEncoder extends StringProtocolEncoder { + public Gl200ProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 5a0ff4197..283dbeb37 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,9 +119,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .compile(); private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .number("(d{1,2})?,") // hdop + .number("(d{1,2}.?d?)?,") // hdop .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course + .number("(d{1,3}.?d?)?,") // course .number("(-?d{1,5}.d)?,") // altitude .number("(-?d{1,3}.d{6})?,") // longitude .number("(-?d{1,2}.d{6})?,") // latitude @@ -184,7 +184,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(d+)?,") // power .number("d{1,2},").optional() // report type .number("d{1,2},").optional() // count - .number(",").optional() // reserved + .number("d*,").optional() // reserved .number("(d+),").optional() // battery .expression("((?:") .expression(PATTERN_LOCATION.pattern()) @@ -202,6 +202,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .or() .number("(d{1,7}.d)?,").optional() // odometer .number("(d{1,3})?,") // battery + .or() + .number("(-?d),") // rssi + .number("(d{1,3}),") // battery .groupEnd() .any() .number("(dddd)(dd)(dd)") // date (yyyymmdd) @@ -514,7 +517,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } private void decodeLocation(Position position, Parser parser) { - Integer hdop = parser.nextInt(); + Double hdop = parser.nextDouble(); position.setValid(hdop == null || hdop > 0); position.set(Position.KEY_HDOP, hdop); @@ -848,6 +851,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); } position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); decodeDeviceTime(position, parser); if (ignoreFixTime) { @@ -1224,8 +1229,11 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { case "CAN": result = decodeCan(channel, remoteAddress, sentence); break; + case "CTN": case "FRI": case "GEO": + case "RTL": + case "DOG": case "STR": result = decodeFri(channel, remoteAddress, sentence); break; diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java index 95ef18f20..76278070e 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,8 @@ import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; -import java.util.Date; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.LinkedList; import java.util.List; import java.util.regex.Pattern; @@ -45,8 +46,6 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { .text("*GS") // header .number("d+,") // protocol version .number("(d+),") // imei - .number("(dd)(dd)(dd)") // time (hhmmss) - .number("(dd)(dd)(dd),") // date (ddmmyy) .expression("([^#]*)#?") // data .compile(); @@ -68,6 +67,7 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { .compile(); private void decodeFragment(Position position, String fragment) { + int dataIndex = fragment.indexOf(':'); int index = 0; String[] values; @@ -76,6 +76,7 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { } else { values = fragment.substring(dataIndex + 1).split(";"); } + switch (fragment.substring(0, dataIndex)) { case "GPS": position.setValid(values[index++].equals("A")); @@ -162,8 +163,15 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { position.set("tagData", values[index++]); break; case "IWD": - if (index < values.length && values[index + 1].equals("0")) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, values[index + 2]); + while (index < values.length) { + int sensorIndex = Integer.parseInt(values[index++]); + int dataType = Integer.parseInt(values[index++]); + if (dataType == 0) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, values[index++]); + } else if (dataType == 1) { + index += 1; // temperature sensor serial number + position.set(Position.PREFIX_TEMP + sensorIndex, Double.parseDouble(values[index++])); + } } break; default: @@ -171,42 +179,27 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { } } - private Object decodeData(DeviceSession deviceSession, Date time, String data) { - - List<Position> positions = new LinkedList<>(); - Position position = null; - int index = 0; - String[] fragments = data.split(","); + private Position decodePosition(DeviceSession deviceSession, String sentence) throws ParseException { - while (index < fragments.length) { + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); - if (fragments[index].isEmpty() || Character.isDigit(fragments[index].charAt(0))) { - - if (position != null) { - positions.add(position); - } + int index = 0; + String[] fragments = sentence.split(","); - position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(time); + position.setTime(new SimpleDateFormat("HHmmssddMMyy").parse(fragments[index++])); - if (!fragments[index++].isEmpty()) { - position.set(Position.KEY_EVENT, Integer.parseInt(fragments[index - 1])); + for (; index < fragments.length; index += 1) { + if (!fragments[index].isEmpty()) { + if (fragments[index].matches("\\p{XDigit}+")) { + position.set(Position.KEY_EVENT, Integer.parseInt(fragments[index], 16)); + } else { + decodeFragment(position, fragments[index]); } - - } else { - - decodeFragment(position, fragments[index++]); - } - } - if (position != null) { - positions.add(position); - } - - return positions; + return position; } @Override @@ -256,12 +249,11 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder { } else { - Date time = new Date(); - if (parser.hasNext(6)) { - time = parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY); + List<Position> positions = new LinkedList<>(); + for (String item : parser.next().split("\\$")) { + positions.add(decodePosition(deviceSession, item)); } - - return decodeData(deviceSession, time, parser.next()); + return positions; } } diff --git a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java index 2ef975fe5..a867451aa 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ public class GotopProtocolDecoder extends BaseProtocolDecoder { .number("DATE:(dd)(dd)(dd),") // date (yyddmm) .number("TIME:(dd)(dd)(dd),") // time (hhmmss) .number("LAT:(d+.d+)([NS]),") // latitude - .number("LOT:(d+.d+)([EW]),") // longitude + .number("LO[NT]:(d+.d+)([EW]),") // longitude .text("Speed:").number("(d+.d+),") // speed .expression("([^,]+),") // status .number("(d+)?") // course diff --git a/src/main/java/org/traccar/protocol/Gps103Protocol.java b/src/main/java/org/traccar/protocol/Gps103Protocol.java index 6272a3fd1..5356387ce 100644 --- a/src/main/java/org/traccar/protocol/Gps103Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps103Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ public class Gps103Protocol extends BaseProtocol { pipeline.addLast(new CharacterDelimiterFrameDecoder(2048, false, "\r\n", "\n", ";", "*")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Gps103ProtocolEncoder()); + pipeline.addLast(new Gps103ProtocolEncoder(Gps103Protocol.this)); pipeline.addLast(new Gps103ProtocolDecoder(Gps103Protocol.this)); } }); @@ -51,7 +51,7 @@ public class Gps103Protocol extends BaseProtocol { protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Gps103ProtocolEncoder()); + pipeline.addLast(new Gps103ProtocolEncoder(Gps103Protocol.this)); pipeline.addLast(new Gps103ProtocolDecoder(Gps103Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java index 47ef2f333..7128823ed 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class Gps103ProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { + public Gps103ProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override public String formatValue(String key, Object value) { diff --git a/src/main/java/org/traccar/protocol/GranitProtocol.java b/src/main/java/org/traccar/protocol/GranitProtocol.java index 6785f2a2e..244c3977b 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocol.java +++ b/src/main/java/org/traccar/protocol/GranitProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,7 +28,7 @@ public class GranitProtocol extends BaseProtocol { Command.TYPE_IDENTIFICATION, Command.TYPE_REBOOT_DEVICE, Command.TYPE_POSITION_SINGLE); - setTextCommandEncoder(new GranitProtocolSmsEncoder()); + setTextCommandEncoder(new GranitProtocolSmsEncoder(this)); setSupportedTextCommands( Command.TYPE_REBOOT_DEVICE, Command.TYPE_POSITION_PERIODIC); @@ -36,7 +36,7 @@ public class GranitProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new GranitFrameDecoder()); - pipeline.addLast(new GranitProtocolEncoder()); + pipeline.addLast(new GranitProtocolEncoder(GranitProtocol.this)); pipeline.addLast(new GranitProtocolDecoder(GranitProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java b/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java index 6345ff971..66c2a4973 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,9 +21,14 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class GranitProtocolEncoder extends BaseProtocolEncoder { + public GranitProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeCommand(String commandString) { ByteBuf buffer = Unpooled.buffer(); buffer.writeBytes(commandString.getBytes(StandardCharsets.US_ASCII)); diff --git a/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java b/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java index 7d5518c17..7dd4b2d77 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java +++ b/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,9 +18,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class GranitProtocolSmsEncoder extends StringProtocolEncoder { + public GranitProtocolSmsEncoder(Protocol protocol) { + super(protocol); + } + @Override protected String encodeCommand(Command command) { switch (command.getType()) { diff --git a/src/main/java/org/traccar/protocol/Gt06Protocol.java b/src/main/java/org/traccar/protocol/Gt06Protocol.java index 6e5435cd4..9ec8de098 100644 --- a/src/main/java/org/traccar/protocol/Gt06Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt06Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ public class Gt06Protocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new Gt06FrameDecoder()); - pipeline.addLast(new Gt06ProtocolEncoder()); + pipeline.addLast(new Gt06ProtocolEncoder(Gt06Protocol.this)); pipeline.addLast(new Gt06ProtocolDecoder(Gt06Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 4665290c3..e1ff0b6b6 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -81,11 +81,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_X1_PHOTO_INFO = 0x35; public static final int MSG_X1_PHOTO_DATA = 0x36; public static final int MSG_WIFI_2 = 0x69; + public static final int MSG_GPS_MODULAR = 0x70; public static final int MSG_COMMAND_0 = 0x80; public static final int MSG_COMMAND_1 = 0x81; public static final int MSG_COMMAND_2 = 0x82; public static final int MSG_TIME_REQUEST = 0x8A; public static final int MSG_INFO = 0x94; + public static final int MSG_RFID = 0x9B; public static final int MSG_STRING_INFO = 0x21; public static final int MSG_GPS_2 = 0xA0; public static final int MSG_LBS_2 = 0xA1; @@ -101,6 +103,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_MULTIMEDIA = 0x21; public static final int MSG_BMS_2 = 0x40; public static final int MSG_MULTIMEDIA_2 = 0x41; + public static final int MSG_ALARM = 0x95; private static boolean isSupported(int type) { return hasGps(type) || hasLbs(type) || hasStatus(type); @@ -748,6 +751,39 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); } + } else if (type == MSG_ALARM) { + + DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + + getLastLocation(position, dateBuilder.getDate()); + + short alarmType = buf.readUnsignedByte(); + + switch (alarmType) { + case 0x80: + position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); + break; + case 0x87: + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + break; + case 0x90: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 0x91: + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 0x92: + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + default: + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + break; + } + + position.set("alarmValue", buf.readShort()); + } else { if (dataLength > 0) { @@ -814,7 +850,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); if (subType == 0x00) { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.01); return position; } else if (subType == 0x05) { int flags = buf.readUnsignedByte(); @@ -824,7 +860,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (subType == 0x0a) { buf.skipBytes(8); // imei buf.skipBytes(8); // imsi - position.set("iccid", ByteBufUtil.hexDump(buf.readSlice(8))); + position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(8))); return position; } else if (subType == 0x0d) { if (buf.getByte(buf.readerIndex()) != '!') { @@ -942,6 +978,22 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_RFID) { + + getLastLocation(position, null); + + buf.readUnsignedByte(); // external device type code + buf.readUnsignedByte(); // card type + position.set( + Position.KEY_DRIVER_UNIQUE_ID, + buf.readCharSequence(buf.readableBytes() - 9, StandardCharsets.US_ASCII).toString()); + + return position; + + } else if (type == MSG_GPS_MODULAR) { + + return decodeExtendedModular(channel, buf, deviceSession, type); + } else { return decodeExtendedOther(channel, buf, deviceSession, type); @@ -951,6 +1003,84 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } + private Object decodeExtendedModular(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + while (buf.readableBytes() > 6) { + int moduleType = buf.readUnsignedShort(); + int moduleLength = buf.readUnsignedShort(); + switch (moduleType) { + case 0x18: + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + break; + case 0x28: + position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); + break; + case 0x29: + position.set(Position.KEY_INDEX, buf.readUnsignedInt()); + break; + case 0x2a: + int input = buf.readUnsignedByte(); + position.set(Position.KEY_DOOR, BitUtil.to(input, 4) > 0); + position.set("tamper", BitUtil.from(input, 4) > 0); + break; + case 0x2b: + int event = buf.readUnsignedByte(); + switch (event) { + case 0x11: + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + break; + case 0x12: + position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + break; + case 0x13: + position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + break; + case 0x14: + position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + break; + default: + break; + } + position.set(Position.KEY_EVENT, event); + break; + case 0x2e: + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + break; + case 0x33: + position.setTime(new Date(buf.readUnsignedInt() * 1000)); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.setAltitude(buf.readShort()); + + double latitude = buf.readUnsignedInt() / 60.0 / 30000.0; + double longitude = buf.readUnsignedInt() / 60.0 / 30000.0; + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + + int flags = buf.readUnsignedShort(); + position.setCourse(BitUtil.to(flags, 10)); + position.setValid(BitUtil.check(flags, 12)); + + if (!BitUtil.check(flags, 10)) { + latitude = -latitude; + } + if (BitUtil.check(flags, 11)) { + longitude = -longitude; + } + + position.setLatitude(latitude); + position.setLongitude(longitude); + break; + default: + buf.skipBytes(moduleLength); + break; + } + } + + return position; + } + private Object decodeExtendedOther(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { Position position = null; diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index 05560229f..9115ba10f 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,14 +21,20 @@ import org.traccar.BaseProtocolEncoder; import org.traccar.Context; import org.traccar.helper.Checksum; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.charset.StandardCharsets; public class Gt06ProtocolEncoder extends BaseProtocolEncoder { + public Gt06ProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeContent(long deviceId, String content) { - boolean language = Context.getIdentityManager().lookupAttributeBoolean(deviceId, "gt06.language", false, true); + boolean language = Context.getIdentityManager() + .lookupAttributeBoolean(deviceId, getProtocolName() + ".language", false, false, true); ByteBuf buf = Unpooled.buffer(); @@ -61,13 +67,18 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { protected Object encodeCommand(Command command) { boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), "gt06.alternative", false, true); + command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + + String password = Context.getIdentityManager() + .getDevicePassword(command.getDeviceId(), getProtocolName(), "123456"); switch (command.getType()) { case Command.TYPE_ENGINE_STOP: - return encodeContent(command.getDeviceId(), alternative ? "DYD,123456#" : "Relay,1#"); + return encodeContent(command.getDeviceId(), + alternative ? "DYD," + password + "#" : "Relay,1#"); case Command.TYPE_ENGINE_RESUME: - return encodeContent(command.getDeviceId(), alternative ? "HFYD,123456#" : "Relay,0#"); + return encodeContent(command.getDeviceId(), + alternative ? "HFYD," + password + "#" : "Relay,0#"); case Command.TYPE_CUSTOM: return encodeContent(command.getDeviceId(), command.getString(Command.KEY_DATA)); default: diff --git a/src/main/java/org/traccar/protocol/H02Protocol.java b/src/main/java/org/traccar/protocol/H02Protocol.java index 251beac5e..b897d83ad 100644 --- a/src/main/java/org/traccar/protocol/H02Protocol.java +++ b/src/main/java/org/traccar/protocol/H02Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ public class H02Protocol extends BaseProtocol { int messageLength = Context.getConfig().getInteger(getName() + ".messageLength"); pipeline.addLast(new H02FrameDecoder(messageLength)); pipeline.addLast(new StringEncoder()); - pipeline.addLast(new H02ProtocolEncoder()); + pipeline.addLast(new H02ProtocolEncoder(H02Protocol.this)); pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this)); } }); @@ -46,7 +46,7 @@ public class H02Protocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new StringEncoder()); - pipeline.addLast(new H02ProtocolEncoder()); + pipeline.addLast(new H02ProtocolEncoder(H02Protocol.this)); pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java index 22bbe4441..137689a67 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java @@ -554,9 +554,18 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { String sentence = buf.toString(StandardCharsets.US_ASCII).trim(); int typeStart = sentence.indexOf(',', sentence.indexOf(',') + 1) + 1; int typeEnd = sentence.indexOf(',', typeStart); + if (typeEnd < 0) { + typeEnd = sentence.indexOf('#', typeStart); + } if (typeEnd > 0) { String type = sentence.substring(typeStart, typeEnd); switch (type) { + case "V0": + case "HTBT": + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(sentence, remoteAddress)); + } + return null; case "NBR": return decodeLbs(sentence, channel, remoteAddress); case "LINK": diff --git a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java index 614a07dd1..7a765332c 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java @@ -1,6 +1,6 @@ /* * Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com) - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package org.traccar.protocol; import org.traccar.Context; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; import java.util.Date; @@ -26,6 +27,10 @@ public class H02ProtocolEncoder extends StringProtocolEncoder { private static final String MARKER = "HQ"; + public H02ProtocolEncoder(Protocol protocol) { + super(protocol); + } + private Object formatCommand(Date time, String uniqueId, String type, String... params) { StringBuilder result = new StringBuilder( @@ -55,7 +60,7 @@ public class H02ProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_POSITION_PERIODIC: String frequency = command.getAttributes().get(Command.KEY_FREQUENCY).toString(); if (Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), "h02.alternative", false, true)) { + command.getDeviceId(), getProtocolName() + ".alternative", false, false, true)) { return formatCommand(time, uniqueId, "D1", frequency); } else { return formatCommand(time, uniqueId, "S71", "22", frequency); diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 8a937a194..9449e2d5c 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -83,7 +83,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { int subtype = buf.readUnsignedShort(); int length = buf.readUnsignedShort() - 4; if (subtype == 0x0003) { - String imei = buf.readSlice(length).toString(StandardCharsets.US_ASCII); + String imei = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession != null && channel != null) { ByteBuf content = Unpooled.buffer(); @@ -117,7 +117,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, BitUtil.check(status, 14)); position.set(Position.KEY_EVENT, buf.readUnsignedShort()); - String time = buf.readSlice(12).toString(StandardCharsets.US_ASCII); + String time = buf.readCharSequence(12, StandardCharsets.US_ASCII).toString(); DateBuilder dateBuilder = new DateBuilder() .setYear(Integer.parseInt(time.substring(0, 2))) @@ -138,9 +138,33 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, buf.readUnsignedShort() * 1000); while (buf.readableBytes() > 4) { - buf.readUnsignedShort(); // subtype + int subtype = buf.readUnsignedShort(); int length = buf.readUnsignedShort() - 4; - buf.skipBytes(length); + switch (subtype) { + case 0x0001: + position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); + position.set(Position.KEY_RPM, buf.readUnsignedShort()); + position.set("averageSpeed", buf.readUnsignedByte()); + buf.readUnsignedShort(); // interval fuel consumption + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort()); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4); + buf.readUnsignedInt(); // trip id + break; + case 0x0005: + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + position.set(Position.KEY_HDOP, buf.readUnsignedByte()); + buf.readUnsignedInt(); // run time + break; + case 0x0009: + position.set( + Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString()); + break; + default: + buf.skipBytes(length); + break; + } } sendResponse(channel, MSG_POSITION_RSP, index, null); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocol.java b/src/main/java/org/traccar/protocol/HuabaoProtocol.java index 44c9f7ac7..791672b85 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocol.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ public class HuabaoProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new HuabaoFrameDecoder()); - pipeline.addLast(new HuabaoProtocolEncoder()); + pipeline.addLast(new HuabaoProtocolEncoder(HuabaoProtocol.this)); pipeline.addLast(new HuabaoProtocolDecoder(HuabaoProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 6e2e1377b..fceefa73a 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -58,7 +58,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { buf.writeShort(type); buf.writeShort(data.readableBytes()); buf.writeBytes(id); - buf.writeShort(1); // index + buf.writeShort(0); // index buf.writeBytes(data); data.release(); buf.writeByte(Checksum.xor(buf.nioBuffer(1, buf.readableBytes() - 1))); @@ -131,7 +131,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { ByteBuf response = Unpooled.buffer(); response.writeShort(index); response.writeByte(RESULT_SUCCESS); - response.writeBytes("authentication".getBytes(StandardCharsets.US_ASCII)); + response.writeBytes(ByteBufUtil.hexDump(id).getBytes(StandardCharsets.US_ASCII)); channel.writeAndFlush(new NetworkMessage( formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, response), remoteAddress)); } @@ -197,20 +197,44 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { while (buf.readableBytes() > 2) { int subtype = buf.readUnsignedByte(); int length = buf.readUnsignedByte(); + int endIndex = buf.readerIndex() + length; switch (subtype) { case 0x01: position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100); break; + case 0x02: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.1); + break; case 0x30: position.set(Position.KEY_RSSI, buf.readUnsignedByte()); break; case 0x31: position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; + case 0x91: + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.1); + position.set(Position.KEY_RPM, buf.readUnsignedShort()); + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); + position.set(Position.KEY_THROTTLE, buf.readUnsignedByte() * 100 / 255); + position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte() * 100 / 255); + position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); + buf.readUnsignedShort(); + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01); + buf.readUnsignedShort(); + buf.readUnsignedInt(); + buf.readUnsignedShort(); + position.set(Position.KEY_FUEL_USED, buf.readUnsignedShort() * 0.01); + break; + case 0x94: + if (length > 0) { + position.set( + Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString()); + } + break; default: - buf.skipBytes(length); break; } + buf.readerIndex(endIndex); } return position; @@ -233,3 +257,4 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } } + diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java index 7759790c4..40d07230d 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java @@ -21,17 +21,22 @@ import org.traccar.BaseProtocolEncoder; import org.traccar.Context; import org.traccar.helper.DataConverter; import org.traccar.model.Command; +import org.traccar.Protocol; import java.text.SimpleDateFormat; import java.util.Date; public class HuabaoProtocolEncoder extends BaseProtocolEncoder { + public HuabaoProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), "huabao.alternative", false, true); + command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); ByteBuf id = Unpooled.wrappedBuffer( DataConverter.parseHex(getUniqueId(command.getDeviceId()))); diff --git a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java index 8c1b9b480..d76d9c92e 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java @@ -44,7 +44,7 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { .expression("[^,]+,") // vendor .expression("[^,]+,") // firmware version .expression("(..),") // status - .number("(d+),") // event + .number("(d+),").optional() // event .expression("([LH]),") // history .or() .expression("([^,]+),") // type @@ -56,7 +56,7 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { .expression("[^,]*,") // vehicle registration .number("([01]),").optional() // valid .groupEnd() - .number("(dd),?(dd),?(dddd),") // date (ddmmyyyy) + .number("(dd),?(dd),?(d{2,4}),") // date (ddmmyyyy) .number("(dd),?(dd),?(dd),") // time (hhmmss) .expression("([01AV]),").optional() // valid .number("(d+.d+),([NS]),") // latitude @@ -69,16 +69,15 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { .number("(d+.?d*),") // altitude .number("d+.?d*,") // pdop .number("d+.?d*,") // hdop - .expression("[^,]*,") + .expression("[^,]*,") // operator .number("([01]),") // ignition .number("([01]),") // charging .number("(d+.?d*),") // power .number("(d+.?d*),") // battery .number("([01]),") // emergency .expression("[CO]?,") // tamper - .number("((?:x+,){5}") // main cell - .number("(?:-?x+,){12})") // other cells - .number("([01]{4}),") // inputs + .expression("(.*),") // cells + .number("([012]{4}),") // inputs .number("([01]{2}),") // outputs .groupBegin() .number("d+,") // index @@ -202,16 +201,22 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { int lac = Integer.parseInt(cells[3], 16); int cid = Integer.parseInt(cells[4], 16); Network network = new Network(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(cells[0]))); - for (int i = 0; i < 4; i++) { - lac = Integer.parseInt(cells[5 + 3 * i + 1], 16); - cid = Integer.parseInt(cells[5 + 3 * i + 2], 16); - if (lac > 0 && cid > 0) { - network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + if (!cells[5].startsWith("(")) { + for (int i = 0; i < 4; i++) { + lac = Integer.parseInt(cells[5 + 3 * i + 1], 16); + cid = Integer.parseInt(cells[5 + 3 * i + 2], 16); + if (lac > 0 && cid > 0) { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + } } } position.setNetwork(network); - position.set(Position.KEY_INPUT, parser.nextBinInt()); + String input = parser.next(); + if (input.charAt(input.length() - 1) == '2') { + input = input.substring(0, input.length() - 1) + '0'; + } + position.set(Position.KEY_INPUT, Integer.parseInt(input, 2)); position.set(Position.KEY_OUTPUT, parser.nextBinInt()); } diff --git a/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java b/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java index ebbbd87cd..f82b8e3ac 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java @@ -17,9 +17,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class ItsProtocolEncoder extends StringProtocolEncoder { + public ItsProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java b/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java index b5d060ecc..bfefb94a7 100644 --- a/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java @@ -35,7 +35,7 @@ public class Jt600FrameDecoder extends BaseFrameDecoder { char type = (char) buf.getByte(buf.readerIndex()); if (type == '$') { - boolean longFormat = buf.getUnsignedByte(buf.readerIndex() + 1) == 0x75; + boolean longFormat = Jt600ProtocolDecoder.isLongFormat(buf, buf.readerIndex() + 1); int length = buf.getUnsignedShort(buf.readerIndex() + (longFormat ? 8 : 7)) + 10; if (length <= buf.readableBytes()) { return buf.readRetainedSlice(length); diff --git a/src/main/java/org/traccar/protocol/Jt600Protocol.java b/src/main/java/org/traccar/protocol/Jt600Protocol.java index 97c5fa6ce..37c82f741 100644 --- a/src/main/java/org/traccar/protocol/Jt600Protocol.java +++ b/src/main/java/org/traccar/protocol/Jt600Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ public class Jt600Protocol extends BaseProtocol { protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new Jt600FrameDecoder()); pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Jt600ProtocolEncoder()); + pipeline.addLast(new Jt600ProtocolEncoder(Jt600Protocol.this)); pipeline.addLast(new Jt600ProtocolDecoder(Jt600Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index 1351706e2..f456cd1ef 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,13 +86,17 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { } + static boolean isLongFormat(ByteBuf buf, int flagIndex) { + return buf.getUnsignedByte(flagIndex) >> 4 == 0x7; + } + private List<Position> decodeBinary(ByteBuf buf, Channel channel, SocketAddress remoteAddress) { List<Position> positions = new LinkedList<>(); buf.readByte(); // header - boolean longFormat = buf.getUnsignedByte(buf.readerIndex()) == 0x75; + boolean longFormat = isLongFormat(buf, buf.readerIndex()); String id = String.valueOf(Long.parseLong(ByteBufUtil.hexDump(buf.readSlice(5)))); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); @@ -170,6 +174,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { if (protocolVersion == 0x17) { buf.readUnsignedByte(); // geofence id buf.skipBytes(3); // reserved + buf.skipBytes(buf.readableBytes() - 1); } } else if (version == 1) { diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java index fe5c63c32..199467a38 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,14 @@ import java.util.TimeZone; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class Jt600ProtocolEncoder extends StringProtocolEncoder { + public Jt600ProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/KhdProtocol.java b/src/main/java/org/traccar/protocol/KhdProtocol.java index cec7158ed..f77f4c311 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocol.java +++ b/src/main/java/org/traccar/protocol/KhdProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ public class KhdProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LengthFieldBasedFrameDecoder(512, 3, 2)); - pipeline.addLast(new KhdProtocolEncoder()); + pipeline.addLast(new KhdProtocolEncoder(KhdProtocol.this)); pipeline.addLast(new KhdProtocolDecoder(KhdProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java index c66129283..4a8df26c8 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,12 +20,17 @@ import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.model.Command; +import org.traccar.Protocol; public class KhdProtocolEncoder extends BaseProtocolEncoder { public static final int MSG_CUT_OIL = 0x39; public static final int MSG_RESUME_OIL = 0x38; + public KhdProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeCommand(int command, String uniqueId) { ByteBuf buf = Unpooled.buffer(); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocol.java b/src/main/java/org/traccar/protocol/LaipacProtocol.java index 923b08a16..1d561dbd2 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocol.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.traccar.protocol; import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; +import org.traccar.model.Command; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; @@ -25,12 +26,19 @@ import org.traccar.TrackerServer; public class LaipacProtocol extends BaseProtocol { public LaipacProtocol() { + + setSupportedDataCommands( + Command.TYPE_CUSTOM, + Command.TYPE_POSITION_SINGLE, + Command.TYPE_REBOOT_DEVICE); + addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); + pipeline.addLast(new LaipacProtocolEncoder(LaipacProtocol.this)); pipeline.addLast(new LaipacProtocolDecoder(LaipacProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 2f3cbb1b9..0c72568f3 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -37,29 +38,44 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final Pattern PATTERN = new PatternBuilder() + public static final String DEFAULT_DEVICE_PASSWORD = "00000000"; + + private static final Pattern PATTERN_EAVSYS = new PatternBuilder() + .text("$EAVSYS,") + .expression("([^,]+),") // identifier + .expression("([0-9]+),") // iccid + .expression("(\\+?[0-9]+)?,") // sim phone number + .expression("(?:[^,]*),") // owner name + .expression("([^,]*)?") // firmware version + .text("*") + .number("(xx)") // checksum + .compile(); + + private static final Pattern PATTERN_AVRMC = new PatternBuilder() .text("$AVRMC,") .expression("([^,]+),") // identifier .number("(dd)(dd)(dd),") // time (hhmmss) .expression("([AVRPavrp]),") // validity .number("(dd)(dd.d+),") // latitude - .expression("([NS]),") + .expression("([NS]),") // latitude hemisphere .number("(ddd)(dd.d+),") // longitude - .number("([EW]),") + .number("([EW]),") // longitude hemisphere .number("(d+.d+),") // speed .number("(d+.d+),") // course .number("(dd)(dd)(dd),") // date (ddmmyy) - .expression("([abZXTSMHFE86430]),") // event code + .expression("([0-9A-Za-z]),") // event code .expression("([\\d.]+),") // battery voltage .number("(d+),") // current mileage .number("(d),") // gps status .number("(d+),") // adc1 .number("(d+)") // adc2 - .number(",(xxxx)") // lac - .number("(xxxx),") // cid - .number("(ddd)") // mcc - .number("(ddd)") // mnc + .number(",(xxxx|x)") // lac | lac+cid = 0 + .number("(xxxx),") // cid | nothing + .number("(ddd|d)") // mcc | mcc+mnc = 0 + .number("(ddd)") // mnc | nothing .optional(4) + .expression(",([^*]*)") // anything remaining (be forward compatible) + .optional(1) .text("*") .number("(xx)") // checksum .compile(); @@ -68,6 +84,8 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { switch (event) { case "Z": return Position.ALARM_LOW_BATTERY; + case "Y": + return Position.ALARM_TOW; case "X": return Position.ALARM_GEOFENCE_ENTER; case "T": @@ -81,6 +99,8 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_GEOFENCE_EXIT; case "6": return Position.ALARM_OVERSPEED; + case "5": + return Position.ALARM_POWER_CUT; case "3": return Position.ALARM_SOS; default: @@ -88,23 +108,77 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { } } - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + private String decodeEvent(String event, Position position) { - String sentence = (String) msg; + if (event.length() == 1) { + char inputStatus = event.charAt(0); + if (inputStatus >= 'A' && inputStatus <= 'D') { + int inputStatusInt = inputStatus - 'A'; + position.set(Position.PREFIX_IN + 1, inputStatusInt & 1); + position.set(Position.PREFIX_IN + 2, inputStatusInt & 2); + return null; + } + } - if (sentence.startsWith("$ECHK") && channel != null) { - channel.writeAndFlush(new NetworkMessage(sentence + "\r\n", remoteAddress)); // heartbeat - return null; + return event; + } + + private void sendEventResponse( + String event, String devicePassword, Channel channel, SocketAddress remoteAddress) { + + String responseCode = null; + + switch (event) { + case "3": + responseCode = "d"; + break; + case "S": + case "T": + responseCode = "t"; + break; + case "X": + case "4": + responseCode = "x"; + break; + case "Y": + responseCode = "y"; + break; + case "Z": + responseCode = "z"; + break; + default: + break; + } + + if (responseCode != null) { + String response = "$AVCFG," + devicePassword + "," + responseCode; + response += Checksum.nmea(response) + "\r\n"; + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + + } + + private void sendAcknowledge( + String status, String event, String checksum, Channel channel, SocketAddress remoteAddress) { + + if (Character.isLowerCase(status.charAt(0))) { + String response = "$EAVACK," + event + "," + checksum; + response += Checksum.nmea(response) + "\r\n"; + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } - Parser parser = new Parser(PATTERN, sentence); + } + + protected Object decodeEavsys( + String sentence, Channel channel, SocketAddress remoteAddress) { + + Parser parser = new Parser(PATTERN_EAVSYS, sentence); if (!parser.matches()) { return null; } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + DeviceSession deviceSession = + getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } @@ -112,6 +186,32 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + getLastLocation(position, null); + + position.set(Position.KEY_ICCID, parser.next()); + position.set(Position.KEY_PHONE, parser.next()); + position.set(Position.KEY_VERSION_FW, parser.next()); + + return position; + } + + protected Object decodeAvrmc( + String sentence, Channel channel, SocketAddress remoteAddress) { + + Parser parser = new Parser(PATTERN_AVRMC, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = + getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + + position.setDeviceId(deviceSession.getDeviceId()); DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); @@ -130,9 +230,9 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { String event = parser.next(); position.set(Position.KEY_ALARM, decodeAlarm(event)); - position.set(Position.KEY_EVENT, event); + position.set(Position.KEY_EVENT, decodeEvent(event, position)); position.set(Position.KEY_BATTERY, Double.parseDouble(parser.next().replaceAll("\\.", "")) * 0.001); - position.set(Position.KEY_ODOMETER, parser.nextDouble()); + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_GPS, parser.nextInt()); position.set(Position.PREFIX_ADC + 1, parser.nextDouble() * 0.001); position.set(Position.PREFIX_ADC + 2, parser.nextDouble() * 0.001); @@ -145,23 +245,39 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid))); } + parser.next(); // unused + String checksum = parser.next(); if (channel != null) { - if (event.equals("3")) { - channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,d*31\r\n", remoteAddress)); - } else if (event.equals("X") || event.equals("4")) { - channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,x*2D\r\n", remoteAddress)); - } else if (event.equals("Z")) { - channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,z*2F\r\n", remoteAddress)); - } else if (Character.isLowerCase(status.charAt(0))) { - String response = "$EAVACK," + event + "," + checksum; - response += Checksum.nmea(response) + "\r\n"; - channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); - } + + sendAcknowledge(status, event, checksum, channel, remoteAddress); + + String devicePassword = Context.getIdentityManager() + .getDevicePassword(deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); + sendEventResponse(event, devicePassword, channel, remoteAddress); } return position; } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + + if (sentence.startsWith("$ECHK")) { + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(sentence + "\r\n", remoteAddress)); + } + } else if (sentence.startsWith("$EAVSYS")) { + return decodeEavsys(sentence, channel, remoteAddress); + } else if (sentence.startsWith("$AVRMC")) { + return decodeAvrmc(sentence, channel, remoteAddress); + } + + return null; + } + } diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java new file mode 100644 index 000000000..343ac9431 --- /dev/null +++ b/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java @@ -0,0 +1,57 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.traccar.StringProtocolEncoder; +import org.traccar.model.Command; +import org.traccar.helper.Checksum; +import org.traccar.Protocol; + +public class LaipacProtocolEncoder extends StringProtocolEncoder { + + public LaipacProtocolEncoder(Protocol protocol) { + super(protocol); + } + + @Override + protected String formatCommand(Command command, String format, String... keys) { + String sentence = super.formatCommand(command, "$" + format, keys); + sentence += Checksum.nmea(sentence) + "\r\n"; + return sentence; + } + + @Override + protected Object encodeCommand(Command command) { + + initDevicePassword(command, LaipacProtocolDecoder.DEFAULT_DEVICE_PASSWORD); + + switch (command.getType()) { + case Command.TYPE_CUSTOM: + return formatCommand(command, "{%s}", + Command.KEY_DATA); + case Command.TYPE_POSITION_SINGLE: + return formatCommand(command, "AVREQ,{%s},1", + Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_REBOOT_DEVICE: + return formatCommand(command, "AVRESET,{%s},{%s}", + Command.KEY_UNIQUE_ID, Command.KEY_DEVICE_PASSWORD); + default: + return null; + } + + } + +} diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java new file mode 100644 index 000000000..05f63a2d7 --- /dev/null +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2019 Jesse Hills (jesserockz@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class LeafSpyProtocol extends BaseProtocol { + + public LeafSpyProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new HttpResponseEncoder()); + pipeline.addLast(new HttpRequestDecoder()); + pipeline.addLast(new HttpObjectAggregator(16384)); + pipeline.addLast(new LeafSpyProtocolDecoder(LeafSpyProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java new file mode 100644 index 000000000..5b352a961 --- /dev/null +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java @@ -0,0 +1,139 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2019 Jesse Hills (jesserockz@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.handler.codec.http.QueryStringDecoder; +import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.Protocol; +import org.traccar.model.Position; +import org.traccar.NetworkMessage; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class LeafSpyProtocolDecoder extends BaseHttpProtocolDecoder { + + public LeafSpyProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + FullHttpRequest request = (FullHttpRequest) msg; + QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); + Map<String, List<String>> params = decoder.parameters(); + if (params.isEmpty()) { + decoder = new QueryStringDecoder(request.content().toString(StandardCharsets.US_ASCII), false); + params = decoder.parameters(); + } + + Position position = new Position(getProtocolName()); + position.setValid(true); + + for (Map.Entry<String, List<String>> entry : params.entrySet()) { + for (String value : entry.getValue()) { + switch (entry.getKey()) { + case "pass": + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); + if (deviceSession == null) { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + break; + case "Lat": + position.setLatitude(Double.parseDouble(value)); + break; + case "Long": + position.setLongitude(Double.parseDouble(value)); + break; + case "RPM": + position.set(Position.KEY_RPM, Integer.parseInt(value)); + position.setSpeed(convertSpeed(Double.parseDouble(value) / 63, "kmh")); + break; + case "Elv": + position.setAltitude(Double.parseDouble(value)); + break; + case "SOC": + position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value)); + break; + case "user": + position.set(Position.KEY_DRIVER_UNIQUE_ID, value); + break; + case "ChrgMode": + position.set(Position.KEY_CHARGE, Integer.parseInt(value) != 0); + break; + case "Odo": + position.set(Position.KEY_OBD_ODOMETER, Integer.parseInt(value) * 1000); + break; + default: + try { + position.set(entry.getKey(), Double.parseDouble(value)); + } catch (NumberFormatException e) { + switch (value) { + case "true": + position.set(entry.getKey(), true); + break; + case "false": + position.set(entry.getKey(), false); + break; + default: + position.set(entry.getKey(), value); + break; + } + } + break; + } + } + } + + if (position.getFixTime() == null) { + position.setTime(new Date()); + } + + if (position.getLatitude() == 0 && position.getLongitude() == 0) { + getLastLocation(position, position.getDeviceTime()); + } + + if (position.getDeviceId() != 0) { + if (channel != null) { + HttpResponse response = new DefaultFullHttpResponse( + HttpVersion.HTTP_1_1, + HttpResponseStatus.OK, + Unpooled.copiedBuffer("\"status\":\"0\"", StandardCharsets.US_ASCII)); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } + return position; + } else { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); + return null; + } + } + +} diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java index c307c7318..e8a66e49f 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,14 +36,14 @@ public class MeiligaoProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new MeiligaoFrameDecoder()); - pipeline.addLast(new MeiligaoProtocolEncoder()); + pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this)); pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new MeiligaoProtocolEncoder()); + pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this)); pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java index 57cbbe0fc..36e94195c 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,17 @@ import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.charset.StandardCharsets; import java.util.TimeZone; public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { + public MeiligaoProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeContent(long deviceId, int type, ByteBuf content) { ByteBuf buf = Unpooled.buffer(); diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocol.java b/src/main/java/org/traccar/protocol/MeitrackProtocol.java index c887cd3a0..7439ea611 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ public class MeitrackProtocol extends BaseProtocol { protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new MeitrackFrameDecoder()); pipeline.addLast(new StringEncoder()); - pipeline.addLast(new MeitrackProtocolEncoder()); + pipeline.addLast(new MeitrackProtocolEncoder(MeitrackProtocol.this)); pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this)); } }); @@ -45,7 +45,7 @@ public class MeitrackProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new StringEncoder()); - pipeline.addLast(new MeitrackProtocolEncoder()); + pipeline.addLast(new MeitrackProtocolEncoder(MeitrackProtocol.this)); pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java index abb6ec9d4..354e81434 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,16 @@ import org.traccar.Context; import org.traccar.StringProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.model.Command; +import org.traccar.Protocol; import java.util.Map; public class MeitrackProtocolEncoder extends StringProtocolEncoder { + public MeitrackProtocolEncoder(Protocol protocol) { + super(protocol); + } + private Object formatCommand(Command command, char dataId, String content) { String uniqueId = getUniqueId(command.getDeviceId()); int length = 1 + uniqueId.length() + 1 + content.length() + 5; @@ -38,7 +43,7 @@ public class MeitrackProtocolEncoder extends StringProtocolEncoder { Map<String, Object> attributes = command.getAttributes(); boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), "meitrack.alternative", false, true); + command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); switch (command.getType()) { case Command.TYPE_POSITION_SINGLE: diff --git a/src/main/java/org/traccar/protocol/MictrackProtocol.java b/src/main/java/org/traccar/protocol/MictrackProtocol.java new file mode 100644 index 000000000..c8d64fd81 --- /dev/null +++ b/src/main/java/org/traccar/protocol/MictrackProtocol.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class MictrackProtocol extends BaseProtocol { + + public MictrackProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new LineBasedFrameDecoder(1024)); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this)); + } + }); + addServer(new TrackerServer(true, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java new file mode 100644 index 000000000..a2fccb707 --- /dev/null +++ b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java @@ -0,0 +1,181 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.Protocol; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; + +import java.net.SocketAddress; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class MictrackProtocolDecoder extends BaseProtocolDecoder { + + public MictrackProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private Date decodeTime(String data) throws ParseException { + DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + return dateFormat.parse(data); + } + + private String decodeAlarm(int event) { + switch (event) { + case 5: + return Position.ALARM_SOS; + case 8: + return Position.ALARM_LOW_BATTERY; + case 9: + return Position.ALARM_GEOFENCE_ENTER; + case 10: + return Position.ALARM_GEOFENCE_EXIT; + case 12: + return Position.ALARM_POWER_OFF; + default: + return null; + } + } + + private void decodeLocation(Position position, String data) throws ParseException { + int index = 0; + String[] values = data.split("\\+"); + + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + + position.setValid(true); + position.setTime(decodeTime(values[index++])); + position.setLatitude(Double.parseDouble(values[index++])); + position.setLongitude(Double.parseDouble(values[index++])); + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); + position.setCourse(Integer.parseInt(values[index++])); + + int event = Integer.parseInt(values[index++]); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); + position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.001); + } + + private void decodeCell(Network network, String data) { + String[] values = data.split(","); + int length = values.length % 5 == 0 ? 5 : 4; + for (int i = 0; i < values.length / length; i++) { + int mnc = Integer.parseInt(values[i * length]); + int cid = Integer.parseInt(values[i * length + 1]); + int lac = Integer.parseInt(values[i * length + 2]); + int mcc = Integer.parseInt(values[i * length + 3]); + network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + } + } + + private void decodeWifi(Network network, String data) { + String[] values = data.split(","); + for (int i = 0; i < values.length / 2; i++) { + network.addWifiAccessPoint(WifiAccessPoint.from(values[i * 2], Integer.parseInt(values[i * 2 + 1]))); + } + } + + private void decodeNetwork(Position position, String data, boolean hasWifi, boolean hasCell) throws ParseException { + int index = 0; + String[] values = data.split("\\+"); + + getLastLocation(position, decodeTime(values[index++])); + + Network network = new Network(); + + if (hasWifi) { + decodeWifi(network, values[index++]); + } + + if (hasCell) { + decodeCell(network, values[index++]); + } + + position.setNetwork(network); + + int event = Integer.parseInt(values[index++]); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); + position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.001); + } + + private void decodeStatus(Position position, String data) throws ParseException { + int index = 0; + String[] values = data.split("\\+"); + + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + + getLastLocation(position, decodeTime(values[index++])); + + index += 4; // fix values + + int event = Integer.parseInt(values[index++]); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); + position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.001); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String[] fragments = ((String) msg).split(";"); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, fragments[2]); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + switch (fragments[3]) { + case "R0": + decodeLocation(position, fragments[4]); + break; + case "R1": + decodeNetwork(position, fragments[4], true, false); + break; + case "R2": + case "R3": + decodeNetwork(position, fragments[4], false, true); + break; + case "R12": + case "R13": + decodeNetwork(position, fragments[4], true, true); + break; + case "RH": + decodeStatus(position, fragments[4]); + break; + default: + return null; + } + + return position; + } + +} diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java index d4a154053..82534ecd8 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ public class MiniFinderProtocol extends BaseProtocol { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new MiniFinderProtocolEncoder()); + pipeline.addLast(new MiniFinderProtocolEncoder(MiniFinderProtocol.this)); pipeline.addLast(new MiniFinderProtocolDecoder(MiniFinderProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java index 7a3d5b226..36fb9fc2f 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,14 @@ import java.util.TimeZone; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class MiniFinderProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { + public MiniFinderProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override public String formatValue(String key, Object value) { switch (key) { diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 51b32ae3e..b6f257d2c 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -33,6 +33,7 @@ import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Date; public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { @@ -72,8 +73,13 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // header + int flags = buf.readUnsignedByte(); + buf.readUnsignedShortLE(); // length + buf.readUnsignedShortLE(); // checksum + int index = buf.readUnsignedShortLE(); + int type = buf.readUnsignedByte(); - if (BitUtil.check(buf.readUnsignedByte(), 4) && channel != null) { + if (BitUtil.check(flags, 4) && channel != null) { ByteBuf content = Unpooled.buffer(); content.writeByte(MSG_RESPONSE); @@ -82,21 +88,16 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { ByteBuf response = Unpooled.buffer(); response.writeByte(0xAB); // header - response.writeByte(0); // properties - response.writeShortLE(3); + response.writeByte(0x00); // properties + response.writeShortLE(content.readableBytes()); response.writeShortLE(Checksum.crc16(Checksum.CRC16_XMODEM, content.nioBuffer())); - response.writeShortLE(0); // index + response.writeShortLE(index); response.writeBytes(content); content.release(); channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } - buf.readUnsignedShortLE(); // length - buf.readUnsignedShortLE(); // checksum - buf.readUnsignedShortLE(); // index - int type = buf.readUnsignedByte(); - if (type == MSG_DATA) { Position position = new Position(getProtocolName()); @@ -116,6 +117,10 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { case 0x02: position.set(Position.KEY_ALARM, decodeAlarm(buf.readIntLE())); break; + case 0x14: + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); + break; case 0x20: position.setLatitude(buf.readIntLE() * 0.0000001); position.setLongitude(buf.readIntLE() * 0.0000001); @@ -149,6 +154,12 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { mac.substring(0, mac.length() - 1), rssi)); } break; + case 0x24: + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + long status = buf.readUnsignedIntLE(); + position.set(Position.KEY_BATTERY_LEVEL, BitUtil.from(status, 24)); + position.set(Position.KEY_STATUS, status); + break; case 0x40: buf.readUnsignedIntLE(); // timestamp int heartRate = buf.readUnsignedByte(); diff --git a/src/main/java/org/traccar/protocol/NavisetFrameDecoder.java b/src/main/java/org/traccar/protocol/NavisetFrameDecoder.java new file mode 100644 index 000000000..e5e13b305 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NavisetFrameDecoder.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; +import org.traccar.helper.BitUtil; + +public class NavisetFrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + int length = 2 + BitUtil.to(buf.getUnsignedShortLE(buf.readerIndex()), 12) + 2; + + if (buf.readableBytes() >= length) { + return buf.readRetainedSlice(length); + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/NavisetProtocol.java b/src/main/java/org/traccar/protocol/NavisetProtocol.java new file mode 100644 index 000000000..78755ea4d --- /dev/null +++ b/src/main/java/org/traccar/protocol/NavisetProtocol.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class NavisetProtocol extends BaseProtocol { + + public NavisetProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new NavisetFrameDecoder()); + pipeline.addLast(new NavisetProtocolDecoder(NavisetProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java new file mode 100644 index 000000000..10d71d76c --- /dev/null +++ b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java @@ -0,0 +1,249 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +public class NavisetProtocolDecoder extends BaseProtocolDecoder { + + public NavisetProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public static final int MSG_HEADER = 0b00; + public static final int MSG_DATA = 0b01; + public static final int MSG_RESPONSE = 0b10; + public static final int MSG_RESERVE = 0b11; + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeByte(0x01); + response.writeShortLE(buf.getUnsignedShortLE(buf.writerIndex() - 2)); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } + + int length = buf.readUnsignedShortLE(); + int type = BitUtil.between(length, 14, 16); + buf.readUnsignedShortLE(); // device number + + if (type == MSG_HEADER) { + + getDeviceSession(channel, remoteAddress, buf.readCharSequence(15, StandardCharsets.US_ASCII).toString()); + + } else if (type == MSG_DATA) { + + List<Position> positions = new LinkedList<>(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + int blockMask = buf.readUnsignedByte(); + + while (buf.readableBytes() > 2) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); + position.set(Position.KEY_STATUS, buf.readUnsignedByte()); + position.setValid(true); + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + position.setLatitude(buf.readUnsignedIntLE() * 0.000001); + position.setLongitude(buf.readUnsignedIntLE() * 0.000001); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE() * 0.1)); + + if (BitUtil.check(blockMask, 0)) { + int dataMask = buf.readUnsignedByte(); + if (BitUtil.check(dataMask, 0)) { + int satellites = buf.readUnsignedByte(); + position.setValid(BitUtil.check(satellites, 7)); + position.set(Position.KEY_SATELLITES, BitUtil.to(satellites, 7)); + } + if (BitUtil.check(dataMask, 1)) { + position.setCourse(buf.readUnsignedShortLE() * 0.1); + } + if (BitUtil.check(dataMask, 2)) { + position.setAltitude(buf.readShortLE()); + } + if (BitUtil.check(dataMask, 3)) { + position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); + } + if (BitUtil.check(dataMask, 4)) { + position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); + } + if (BitUtil.check(dataMask, 5)) { + position.set(Position.KEY_INPUT, buf.readUnsignedByte()); + position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); + } + if (BitUtil.check(dataMask, 6)) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + } + if (BitUtil.check(dataMask, 7)) { + buf.skipBytes(6); // accelerometer + } + } + + if (BitUtil.check(blockMask, 1)) { + int dataMask = buf.readUnsignedByte(); + for (int i = 0; i < 8; i++) { + if (BitUtil.check(dataMask, i)) { + position.set(Position.PREFIX_ADC + (i + 1), buf.readUnsignedShortLE()); + } + } + } + + if (BitUtil.check(blockMask, 2)) { + int dataMask = buf.readUnsignedByte(); + if (BitUtil.check(dataMask, 0)) { + position.set(Position.KEY_DEVICE_TEMP, (int) buf.readByte()); + } + if (BitUtil.check(dataMask, 1)) { + buf.skipBytes(6); // key code + } + if (BitUtil.check(dataMask, 2)) { + position.set(Position.PREFIX_TEMP + 1, (int) buf.readByte()); + position.set(Position.PREFIX_TEMP + 2, (int) buf.readByte()); + } + if (BitUtil.check(dataMask, 3)) { + position.set(Position.PREFIX_TEMP + 3, (int) buf.readByte()); + position.set(Position.PREFIX_TEMP + 4, (int) buf.readByte()); + } + if (BitUtil.check(dataMask, 4)) { + position.set(Position.PREFIX_TEMP + 5, (int) buf.readByte()); + position.set(Position.PREFIX_TEMP + 6, (int) buf.readByte()); + position.set(Position.PREFIX_TEMP + 7, (int) buf.readByte()); + position.set(Position.PREFIX_TEMP + 8, (int) buf.readByte()); + } + if (BitUtil.check(dataMask, 5)) { + position.set(Position.KEY_HOURS, buf.readUnsignedShortLE() / 60.0); + } + if (BitUtil.check(dataMask, 6)) { + buf.readUnsignedByte(); // extra status + } + if (BitUtil.check(dataMask, 7)) { + buf.readUnsignedByte(); // geofence + } + } + + if (BitUtil.check(blockMask, 3)) { + int dataMask = buf.readUnsignedByte(); + if (BitUtil.check(dataMask, 0)) { + position.set("fuel1", buf.readUnsignedShortLE()); + } + if (BitUtil.check(dataMask, 1)) { + position.set("fuel2", buf.readUnsignedShortLE()); + } + if (BitUtil.check(dataMask, 2)) { + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShortLE()); + } + if (BitUtil.check(dataMask, 3)) { + buf.skipBytes(18); + } + if (BitUtil.check(dataMask, 4)) { + buf.readUnsignedByte(); // fuel 1 temperature + } + if (BitUtil.check(dataMask, 5)) { + buf.readUnsignedByte(); // fuel 2 temperature + } + if (BitUtil.check(dataMask, 6)) { + buf.readUnsignedShortLE(); // fuel 1 frequency + } + if (BitUtil.check(dataMask, 7)) { + buf.readUnsignedShortLE(); // fuel 2 frequency + } + } + + if (BitUtil.check(blockMask, 4)) { + int dataMask = buf.readUnsignedByte(); + if (BitUtil.check(dataMask, 0)) { + buf.readUnsignedByte(); // fuel level (percentage) + position.set(Position.KEY_RPM, buf.readUnsignedShortLE()); + position.set(Position.KEY_COOLANT_TEMP, (int) buf.readByte()); + } + if (BitUtil.check(dataMask, 1)) { + buf.readUnsignedIntLE(); // fuel consumption + } + if (BitUtil.check(dataMask, 2)) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + } + for (int i = 3; i < 8; i++) { + if (BitUtil.check(dataMask, i)) { + buf.readUnsignedShortLE(); // axle weight + } + } + } + + if (BitUtil.check(blockMask, 4)) { + int dataMask = buf.readUnsignedByte(); + if (BitUtil.check(dataMask, 0)) { + buf.readUnsignedByte(); // speed + } + if (BitUtil.check(dataMask, 1)) { + buf.readUnsignedMediumLE(); // prefix S + } + if (BitUtil.check(dataMask, 2)) { + buf.readUnsignedIntLE(); // prefix P + } + if (BitUtil.check(dataMask, 3)) { + buf.readUnsignedIntLE(); // prefix A or B + } + if (BitUtil.check(dataMask, 4)) { + buf.readUnsignedShortLE(); // prefix R + } + if (BitUtil.check(dataMask, 5)) { + buf.skipBytes(26); + } + if (BitUtil.check(dataMask, 6)) { + buf.readUnsignedIntLE(); // reserved + } + if (BitUtil.check(dataMask, 7)) { + buf.readUnsignedIntLE(); // reserved + } + } + + positions.add(position); + } + + return positions; + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/NoranProtocol.java b/src/main/java/org/traccar/protocol/NoranProtocol.java index 9f3078d6d..3df364c30 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocol.java +++ b/src/main/java/org/traccar/protocol/NoranProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ public class NoranProtocol extends BaseProtocol { addServer(new TrackerServer(true, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new NoranProtocolEncoder()); + pipeline.addLast(new NoranProtocolEncoder(NoranProtocol.this)); pipeline.addLast(new NoranProtocolDecoder(NoranProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java b/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java index 92826c8b2..e02a1313c 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,16 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.charset.StandardCharsets; public class NoranProtocolEncoder extends BaseProtocolEncoder { + public NoranProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeContent(String content) { ByteBuf buf = Unpooled.buffer(12 + 56); diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java new file mode 100644 index 000000000..08991ab64 --- /dev/null +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class PacificTrackProtocol extends BaseProtocol { + + public PacificTrackProtocol() { + addServer(new TrackerServer(true, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new PacificTrackProtocolDecoder(PacificTrackProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java new file mode 100644 index 000000000..199348c54 --- /dev/null +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java @@ -0,0 +1,104 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; + +public class PacificTrackProtocolDecoder extends BaseProtocolDecoder { + + public PacificTrackProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public static int readBitExt(ByteBuf buf) { + int result = 0; + while (buf.isReadable()) { + int b = buf.readUnsignedByte(); + result <<= 7; + result += BitUtil.to(b, 7); + if (BitUtil.check(b, 7)) { + break; + } + } + return result; + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + buf.readByte(); // frame start + readBitExt(buf); // frame control + readBitExt(buf); // frame length + + DeviceSession deviceSession = null; + Position position = new Position(getProtocolName()); + + while (buf.isReadable()) { + + int segmentId = readBitExt(buf); + int segmentLength = readBitExt(buf); + + switch (segmentId) { + case 0x01: + position.set(Position.KEY_EVENT, readBitExt(buf)); + break; + case 0x10: + position.setValid(BitUtil.check(buf.readUnsignedByte(), 4)); + int date = buf.readUnsignedByte(); + DateBuilder dateBuilder = new DateBuilder() + .setDate(2000 + BitUtil.from(date, 4), BitUtil.to(date, 4), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + position.setTime(dateBuilder.getDate()); + position.setLatitude(buf.readUnsignedInt() / 1000000.0 - 90.0); + position.setLongitude(buf.readUnsignedInt() / 1000000.0 - 180.0); + int speedAndCourse = buf.readUnsignedMedium(); + position.setCourse(BitUtil.from(speedAndCourse, 12)); + position.setSpeed(UnitsConverter.knotsFromKph(BitUtil.to(speedAndCourse, 12))); + position.set(Position.KEY_INDEX, buf.readUnsignedShort()); + break; + case 0x100: + String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1); + deviceSession = getDeviceSession(channel, remoteAddress, imei); + break; + default: + buf.skipBytes(segmentLength); + break; + } + } + + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + return position; + } else { + return null; + } + } + +} diff --git a/src/main/java/org/traccar/protocol/PluginProtocol.java b/src/main/java/org/traccar/protocol/PluginProtocol.java new file mode 100644 index 000000000..d5f28da9d --- /dev/null +++ b/src/main/java/org/traccar/protocol/PluginProtocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class PluginProtocol extends BaseProtocol { + + public PluginProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new PluginProtocolDecoder(PluginProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java new file mode 100644 index 000000000..106889ee0 --- /dev/null +++ b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java @@ -0,0 +1,93 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.Protocol; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class PluginProtocolDecoder extends BaseProtocolDecoder { + + public PluginProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .expression("[^0-9,]*,?") + .number("([^,]+),") // device id + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(-?d+.d+),") // longitude + .number("(-?d+.d+),") // latitude + .number("(d+),") // speed + .number("(d+),") // course + .number("(-?d+),") // altitude + .number("(-?d+),") // satellites + .number("d+,") // type + .number("(d+),") // odometer + .number("(d+),") // status + .expression("[^,]*,") + .expression("[^,]*,") + .text("0") + .groupBegin() + .text(",+,") + .number("(d+),") // event + .groupEnd("?") + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setTime(parser.nextDateTime()); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + position.setCourse(parser.nextInt()); + position.setAltitude(parser.nextInt()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_ODOMETER, parser.nextInt()); + position.set(Position.KEY_STATUS, parser.nextInt()); + position.set(Position.KEY_EVENT, parser.nextInt()); + + return position; + } + +} diff --git a/src/main/java/org/traccar/protocol/PretraceProtocol.java b/src/main/java/org/traccar/protocol/PretraceProtocol.java index f753cbdb4..9d35c1c2f 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocol.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ public class PretraceProtocol extends BaseProtocol { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new PretraceProtocolEncoder()); + pipeline.addLast(new PretraceProtocolEncoder(PretraceProtocol.this)); pipeline.addLast(new PretraceProtocolDecoder(PretraceProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java index 9cf951e3b..1083a252e 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,14 @@ import org.traccar.BaseProtocolEncoder; import org.traccar.Context; import org.traccar.helper.Checksum; import org.traccar.model.Command; +import org.traccar.Protocol; public class PretraceProtocolEncoder extends BaseProtocolEncoder { + public PretraceProtocolEncoder(Protocol protocol) { + super(protocol); + } + private String formatCommand(String uniqueId, String data) { String content = uniqueId + data; return String.format("(%s^%02X)", content, Checksum.xor(content)); diff --git a/src/main/java/org/traccar/protocol/Pt215FrameDecoder.java b/src/main/java/org/traccar/protocol/Pt215FrameDecoder.java new file mode 100644 index 000000000..0b3bae914 --- /dev/null +++ b/src/main/java/org/traccar/protocol/Pt215FrameDecoder.java @@ -0,0 +1,55 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; + +public class Pt215FrameDecoder extends BaseFrameDecoder { + + private ByteBuf decodeFrame(ByteBuf buf, int length) { + if (buf.readableBytes() >= length) { + return buf.readRetainedSlice(length); + } + return null; + } + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + if (buf.readableBytes() < 5) { + return null; + } + + int type = buf.getUnsignedByte(buf.readerIndex() + 2 + 1); + switch (type) { + case Pt215ProtocolDecoder.MSG_LOGIN: + return decodeFrame(buf, 15); + case Pt215ProtocolDecoder.MSG_GPS_REALTIME: + case Pt215ProtocolDecoder.MSG_GPS_OFFLINE: + return decodeFrame(buf, 27); + case Pt215ProtocolDecoder.MSG_STATUS: + return decodeFrame(buf, 11); + default: + return null; + + } + } + +} diff --git a/src/main/java/org/traccar/protocol/Pt215Protocol.java b/src/main/java/org/traccar/protocol/Pt215Protocol.java new file mode 100644 index 000000000..31ddc2c7a --- /dev/null +++ b/src/main/java/org/traccar/protocol/Pt215Protocol.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class Pt215Protocol extends BaseProtocol { + + public Pt215Protocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new Pt215FrameDecoder()); + pipeline.addLast(new Pt215ProtocolDecoder(Pt215Protocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java new file mode 100644 index 000000000..48ce7dede --- /dev/null +++ b/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java @@ -0,0 +1,118 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.DateBuilder; +import org.traccar.model.Position; + +import java.net.SocketAddress; + +public class Pt215ProtocolDecoder extends BaseProtocolDecoder { + + public Pt215ProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public static final int MSG_LOGIN = 0x01; + public static final int MSG_HEARTBEAT = 0x08; + public static final int MSG_GPS_REALTIME = 0x10; + public static final int MSG_GPS_OFFLINE = 0x11; + public static final int MSG_STATUS = 0x13; + + private void sendResponse( + Channel channel, SocketAddress remoteAddress, int type, ByteBuf content) { + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeByte('X'); + response.writeByte('X'); + response.writeByte(content != null ? 1 + content.readableBytes() : 1); + response.writeByte(type); + if (content != null) { + response.writeBytes(content); + content.release(); + } + response.writeByte('\r'); + response.writeByte('\n'); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + buf.skipBytes(2); // header + buf.readUnsignedByte(); // length + int type = buf.readUnsignedByte(); + + if (type == MSG_LOGIN) { + + getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(buf.readSlice(8)).substring(1)); + sendResponse(channel, remoteAddress, type, null); + + } else if (type == MSG_GPS_OFFLINE || type == MSG_GPS_REALTIME) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + sendResponse(channel, remoteAddress, type, buf.retainedSlice(buf.readerIndex(), 6)); + + DateBuilder dateBuilder = new DateBuilder() + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + position.setTime(dateBuilder.getDate()); + + double latitude = buf.readUnsignedInt() / 60.0 / 30000.0; + double longitude = buf.readUnsignedInt() / 60.0 / 30000.0; + + int flags = buf.readUnsignedShort(); + position.setCourse(BitUtil.to(flags, 10)); + position.setValid(BitUtil.check(flags, 12)); + + if (!BitUtil.check(flags, 10)) { + latitude = -latitude; + } + if (BitUtil.check(flags, 11)) { + longitude = -longitude; + } + + position.setLatitude(latitude); + position.setLongitude(longitude); + + return position; + + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/Pt502Protocol.java b/src/main/java/org/traccar/protocol/Pt502Protocol.java index 5afb9451d..56444fb42 100644 --- a/src/main/java/org/traccar/protocol/Pt502Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt502Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ public class Pt502Protocol extends BaseProtocol { protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new Pt502FrameDecoder()); pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Pt502ProtocolEncoder()); + pipeline.addLast(new Pt502ProtocolEncoder(Pt502Protocol.this)); pipeline.addLast(new Pt502ProtocolDecoder(Pt502Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java index ed18208cc..ba08b16ae 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,14 @@ import java.util.TimeZone; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class Pt502ProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { + public Pt502ProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override public String formatValue(String key, Object value) { if (key.equals(Command.KEY_TIMEZONE)) { diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java new file mode 100644 index 000000000..c9db10610 --- /dev/null +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.LineBasedFrameDecoder; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class RaceDynamicsProtocol extends BaseProtocol { + + public RaceDynamicsProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new LineBasedFrameDecoder(1500)); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new RaceDynamicsProtocolDecoder(RaceDynamicsProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java new file mode 100644 index 000000000..f441bf8ed --- /dev/null +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java @@ -0,0 +1,171 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Pattern; + +public class RaceDynamicsProtocolDecoder extends BaseProtocolDecoder { + + public RaceDynamicsProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public static final int MSG_LOGIN = 12; + public static final int MSG_LOCATION = 15; + + private static final Pattern PATTERN_LOGIN = new PatternBuilder() + .text("$GPRMC,") + .number("d+,") // type + .number("d{6},") // date + .number("d{6},") // time + .number("(d{15}),") + .compile(); + + private static final Pattern PATTERN_LOCATION = new PatternBuilder() + .number("(dd)(dd)(dd),") // time (hhmmss) + .expression("([AV]),") // validity + .number("(dd)(dd.d+),") // latitude + .expression("([NS]),") + .number("(ddd)(dd.d+),") // longitude + .expression("([EW]),") + .number("(d+),") // speed + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(-?d+),") // altitude + .number("(d+),") // satellites + .number("([01]),") // ignition + .number("(d+),") // index + .text("%,") + .number("([^,]+),") // ibutton + .number("d+,") // acceleration + .number("d+,") // deceleration + .number("[01],") // cruise control + .number("[01],") // seat belt + .number("[01],") // wrong ibutton + .number("(d+),") // power + .number("[01],") // power status + .number("(d+),") // battery + .number("([01]),") // panic + .number("d+,") + .number("d+,") + .number("(d),") // overspeed + .number("d+,") // speed limit + .number("d+,") // tachometer + .number("d+,d+,d+,") // aux + .number("d+,") // geofence id + .number("d+,") // road speed type + .number("d+,") // ibutton count + .number("(d),") // overdriver alert + .any() + .compile(); + + private String imei; + + private void sendResponse(Channel channel, SocketAddress remoteAddress, int type) { + if (channel != null) { + String response = String.format( + "$GPRMC,%1$d,%2$td%2$tm%2$ty,%2$tH%2$tM%2$tS,%3$s,\r\n", type, new Date(), imei); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + + int type = Integer.parseInt(sentence.substring(7, 9)); + + if (type == MSG_LOGIN) { + + Parser parser = new Parser(PATTERN_LOGIN, sentence); + if (parser.matches()) { + imei = parser.next(); + getDeviceSession(channel, remoteAddress, imei); + sendResponse(channel, remoteAddress, type); + } + + } else if (type == MSG_LOCATION) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + List<Position> positions = new LinkedList<>(); + + for (String data : sentence.substring(17, sentence.length() - 3).split(",#,#,")) { + Parser parser = new Parser(PATTERN_LOCATION, data); + if (parser.matches()) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateBuilder dateBuilder = new DateBuilder() + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + + position.setValid(parser.next().equals("A")); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setSpeed(parser.nextDouble()); + + dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + position.setAltitude(parser.nextInt()); + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_IGNITION, parser.nextInt() == 1); + position.set(Position.KEY_INDEX, parser.nextInt()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); + position.set(Position.KEY_POWER, parser.nextInt() * 0.01); + position.set(Position.KEY_BATTERY, parser.nextInt() * 0.01); + position.set(Position.KEY_ALARM, parser.nextInt() > 0 ? Position.ALARM_SOS : null); + position.set(Position.KEY_ALARM, parser.nextInt() > 0 ? Position.ALARM_OVERSPEED : null); + + int overDriver = parser.nextInt(); + if (overDriver > 0) { + position.set("overDriver", overDriver); + } + + positions.add(position); + + } + } + + sendResponse(channel, remoteAddress, type); + + return positions; + + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/RstProtocol.java b/src/main/java/org/traccar/protocol/RstProtocol.java new file mode 100644 index 000000000..10d11d493 --- /dev/null +++ b/src/main/java/org/traccar/protocol/RstProtocol.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class RstProtocol extends BaseProtocol { + + public RstProtocol() { + addServer(new TrackerServer(true, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new RstProtocolDecoder(RstProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/RstProtocolDecoder.java b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java new file mode 100644 index 000000000..071200d6d --- /dev/null +++ b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java @@ -0,0 +1,128 @@ +/* + * Copyright 2019 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class RstProtocolDecoder extends BaseProtocolDecoder { + + public RstProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("RST;") + .expression("([AL]);") // archive + .expression("([^,]+);") // model + .expression("(.{5});") // firmware + .number("(d{9});") // serial number + .number("(d+);") // index + .number("(d+);") // type + .number("(dd)-(dd)-(dddd) ") // event date + .number("(dd):(dd):(dd);") // event time + .number("(dd)-(dd)-(dddd) ") // fix date + .number("(dd):(dd):(dd);") // fix time + .number("(-?d+.d+);") // latitude + .number("(-?d+.d+);") // longitude + .number("(d+);") // speed + .number("(d+);") // course + .number("(-?d+);") // altitude + .number("([01]);") // valid + .number("(d+);") // satellites + .number("(d+);") // hdop + .number("(xx);") // inputs 1 + .number("(xx);") // inputs 2 + .number("(xx);") // inputs 3 + .number("(xx);") // outputs 1 + .number("(xx);") // outputs 2 + .number("(d+.d+);") // power + .number("(d+.d+);") // battery + .number("(d+);") // odometer + .number("(d+);") // rssi + .number("(xx);") // temperature + .number("x{4};") // sensors + .number("(xx);") // status 1 + .number("(xx);") // status 2 + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + String archive = parser.next(); + String model = parser.next(); + String firmware = parser.next(); + String serial = parser.next(); + int index = parser.nextInt(); + int type = parser.nextInt(); + + if (channel != null && archive.equals("A")) { + String response = "RST;A;" + model + ";" + firmware + ";" + serial + ";" + index + ";" + type + ";FIM;"; + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, serial); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setDeviceTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + position.setCourse(parser.nextInt()); + position.setAltitude(parser.nextInt()); + position.setValid(parser.nextInt() > 0); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_HDOP, parser.nextInt()); + position.set(Position.PREFIX_IN + 1, parser.nextHexInt()); + position.set(Position.PREFIX_IN + 2, parser.nextHexInt()); + position.set(Position.PREFIX_IN + 3, parser.nextHexInt()); + position.set(Position.PREFIX_OUT + 1, parser.nextHexInt()); + position.set(Position.PREFIX_OUT + 2, parser.nextHexInt()); + position.set(Position.KEY_POWER, parser.nextDouble()); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + position.set(Position.KEY_ODOMETER, parser.nextInt()); + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.PREFIX_TEMP + 1, (int) parser.nextHexInt().byteValue()); + position.set(Position.KEY_STATUS, parser.nextHexInt() << 8 + parser.nextHexInt()); + + return position; + } + +} diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocol.java b/src/main/java/org/traccar/protocol/RuptelaProtocol.java index a574293cd..b8f72336b 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocol.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ public class RuptelaProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 2, 0)); - pipeline.addLast(new RuptelaProtocolEncoder()); + pipeline.addLast(new RuptelaProtocolEncoder(RuptelaProtocol.this)); pipeline.addLast(new RuptelaProtocolDecoder(RuptelaProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java index 96d0da5a7..51967403d 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java @@ -20,11 +20,16 @@ import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.charset.StandardCharsets; public class RuptelaProtocolEncoder extends BaseProtocolEncoder { + public RuptelaProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeContent(int type, ByteBuf content) { ByteBuf buf = Unpooled.buffer(); diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java index d7836b35d..f9c79fb5b 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; @@ -25,7 +26,9 @@ import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.helper.UnitsConverter; +import org.traccar.model.Network; import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; import javax.json.Json; import javax.json.JsonObject; @@ -46,8 +49,11 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { FullHttpRequest request = (FullHttpRequest) msg; - JsonObject json = Json.createReader(new StringReader(URLDecoder.decode( - request.content().toString(StandardCharsets.UTF_8).split("=")[0], "UTF-8"))).readObject(); + String content = request.content().toString(StandardCharsets.UTF_8); + if (!content.startsWith("{")) { + content = URLDecoder.decode(content.split("=")[0], "UTF-8"); + } + JsonObject json = Json.createReader(new StringReader(content)).readObject(); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, json.getString("device")); if (deviceSession == null) { @@ -58,32 +64,101 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(new Date(json.getInt("time") * 1000L)); - - ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(json.getString("data"))); - try { - int type = buf.readUnsignedByte() >> 4; - if (type == 0) { - - position.setValid(true); - position.setLatitude(buf.readIntLE() * 0.0000001); - position.setLongitude(buf.readIntLE() * 0.0000001); - position.setCourse(buf.readUnsignedByte() * 2); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - - position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.025); - - } else { - - getLastLocation(position, position.getDeviceTime()); + if (json.containsKey("time")) { + position.setTime(new Date(json.getInt("time") * 1000L)); + } else { + position.setTime(new Date()); + } + if (json.containsKey("location")) { + + JsonObject location = json.getJsonObject("location"); + + position.setValid(true); + position.setLatitude(location.getJsonNumber("lat").doubleValue()); + position.setLongitude(location.getJsonNumber("lng").doubleValue()); + + } else { + + String data = json.getString(json.containsKey("data") ? "data" : "payload"); + ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(data)); + try { + int event = buf.readUnsignedByte(); + if (event >> 4 == 0) { + + position.setValid(true); + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); + position.setCourse(buf.readUnsignedByte() * 2); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + + position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.025); + + } else { + + position.set(Position.KEY_EVENT, event); + if (event == 0x22 || event == 0x62) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + + while (buf.isReadable()) { + int type = buf.readUnsignedByte(); + switch (type) { + case 0x01: + position.setValid(true); + position.setLatitude(buf.readMedium()); + position.setLongitude(buf.readMedium()); + break; + case 0x02: + position.setValid(true); + position.setLatitude(buf.readFloat()); + position.setLongitude(buf.readFloat()); + break; + case 0x03: + position.set(Position.PREFIX_TEMP + 1, buf.readByte() * 0.5); + break; + case 0x04: + position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.1); + break; + case 0x05: + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + break; + case 0x06: + String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); + position.setNetwork(new Network(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte()))); + break; + case 0x07: + buf.skipBytes(10); // wifi extended + break; + case 0x08: + buf.skipBytes(6); // accelerometer + break; + case 0x09: + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + break; + default: + buf.readUnsignedByte(); // fence number + break; + } + } + + } + } finally { + buf.release(); } - } finally { - buf.release(); } - position.set(Position.KEY_RSSI, json.getJsonNumber("rssi").doubleValue()); - position.set(Position.KEY_INDEX, json.getInt("seqNumber")); + if (position.getLatitude() == 0 && position.getLongitude() == 0) { + getLastLocation(position, position.getDeviceTime()); + } + + if (json.containsKey("rssi")) { + position.set(Position.KEY_RSSI, json.getJsonNumber("rssi").doubleValue()); + } + if (json.containsKey("seqNumber")) { + position.set(Position.KEY_INDEX, json.getInt("seqNumber")); + } sendResponse(channel, HttpResponseStatus.OK); return position; diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index ed5f81c1c..bad6f03a9 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,21 +34,7 @@ import java.util.regex.Pattern; public class StarLinkProtocolDecoder extends BaseProtocolDecoder { - private String[] dataTags; - private DateFormat dateFormat; - - public StarLinkProtocolDecoder(Protocol protocol) { - super(protocol); - - String format = Context.getConfig().getString( - getProtocolName() + ".format", "#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#," - + "#IN1#,#IN2#,#IN3#,#IN4#,#OUT1#,#OUT2#,#OUT3#,#OUT4#,#LAC#,#CID#,#VIN#,#VBAT#,#DEST#,#IGN#,#ENG#"); - dataTags = format.split(","); - - dateFormat = new SimpleDateFormat( - Context.getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss")); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - } + public static final int MSG_EVENT_REPORT = 6; private static final Pattern PATTERN = new PatternBuilder() .expression(".") // protocol head @@ -61,7 +47,27 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { .number("xx") // checksum .compile(); - public static final int MSG_EVENT_REPORT = 6; + private String[] dataTags; + private DateFormat dateFormat; + + public StarLinkProtocolDecoder(Protocol protocol) { + super(protocol); + + setFormat(Context.getConfig().getString( + getProtocolName() + ".format", "#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#," + + "#IN1#,#IN2#,#IN3#,#IN4#,#OUT1#,#OUT2#,#OUT3#,#OUT4#,#LAC#,#CID#,#VIN#,#VBAT#,#DEST#,#IGN#,#ENG#")); + + setDateFormat(Context.getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss")); + } + + public void setFormat(String format) { + dataTags = format.split(","); + } + + public void setDateFormat(String dateFormat) { + this.dateFormat = new SimpleDateFormat(dateFormat); + this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } private double parseCoordinate(String value) { int minutesIndex = value.indexOf('.') - 2; @@ -151,31 +157,19 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { position.setCourse(Integer.parseInt(data[i])); break; case "#ODO#": - position.set(Position.KEY_ODOMETER, Long.parseLong(data[i]) * 1000); + position.set(Position.KEY_ODOMETER, (long) (Double.parseDouble(data[i]) * 1000)); break; case "#IN1#": - position.set(Position.PREFIX_IN + 1, Integer.parseInt(data[i])); - break; case "#IN2#": - position.set(Position.PREFIX_IN + 2, Integer.parseInt(data[i])); - break; case "#IN3#": - position.set(Position.PREFIX_IN + 3, Integer.parseInt(data[i])); - break; case "#IN4#": - position.set(Position.PREFIX_IN + 4, Integer.parseInt(data[i])); + position.set(Position.PREFIX_IN + dataTags[i].charAt(3), Integer.parseInt(data[i])); break; case "#OUT1#": - position.set(Position.PREFIX_OUT + 1, Integer.parseInt(data[i])); - break; case "#OUT2#": - position.set(Position.PREFIX_OUT + 2, Integer.parseInt(data[i])); - break; case "#OUT3#": - position.set(Position.PREFIX_OUT + 3, Integer.parseInt(data[i])); - break; case "#OUT4#": - position.set(Position.PREFIX_OUT + 4, Integer.parseInt(data[i])); + position.set(Position.PREFIX_OUT + dataTags[i].charAt(3), Integer.parseInt(data[i])); break; case "#LAC#": if (!data[i].isEmpty()) { diff --git a/src/main/java/org/traccar/protocol/SuntechProtocol.java b/src/main/java/org/traccar/protocol/SuntechProtocol.java index 48d6e81c1..7e2c20e6f 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocol.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocol.java @@ -39,7 +39,7 @@ public class SuntechProtocol extends BaseProtocol { pipeline.addLast(new SuntechFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new SuntechProtocolEncoder()); + pipeline.addLast(new SuntechProtocolEncoder(SuntechProtocol.this)); pipeline.addLast(new SuntechProtocolDecoder(SuntechProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index bd485ca70..e40096a77 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -50,7 +50,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { public int getProtocolType(long deviceId) { return Context.getIdentityManager().lookupAttributeInteger( - deviceId, getProtocolName() + ".protocolType", protocolType, true); + deviceId, getProtocolName() + ".protocolType", protocolType, false, true); } public void setHbm(boolean hbm) { @@ -59,7 +59,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { public boolean isHbm(long deviceId) { return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".hbm", hbm, true); + deviceId, getProtocolName() + ".hbm", hbm, false, true); } public void setIncludeAdc(boolean includeAdc) { @@ -68,7 +68,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { public boolean isIncludeAdc(long deviceId) { return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeAdc", includeAdc, true); + deviceId, getProtocolName() + ".includeAdc", includeAdc, false, true); } public void setIncludeRpm(boolean includeRpm) { @@ -77,7 +77,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { public boolean isIncludeRpm(long deviceId) { return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeRpm", includeRpm, true); + deviceId, getProtocolName() + ".includeRpm", includeRpm, false, true); } public void setIncludeTemp(boolean includeTemp) { @@ -86,7 +86,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { public boolean isIncludeTemp(long deviceId) { return Context.getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeTemp", includeTemp, true); + deviceId, getProtocolName() + ".includeTemp", includeTemp, false, true); } private Position decode9( @@ -326,12 +326,40 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { case "UEX": int remaining = Integer.parseInt(values[index++]); while (remaining > 0) { - String value = values[index++]; - String[] pair = value.split("="); - if (pair.length >= 2) { - position.set(pair[0].toLowerCase(), pair[1].trim()); + String attribute = values[index++]; + if (attribute.startsWith("CabAVL")) { + String[] data = attribute.split(","); + double fuel1 = Double.parseDouble(data[2]); + if (fuel1 > 0) { + position.set("fuel1", fuel1); + } + double fuel2 = Double.parseDouble(data[3]); + if (fuel2 > 0) { + position.set("fuel2", fuel2); + } + } else { + String[] pair = attribute.split("="); + if (pair.length >= 2) { + String value = pair[1].trim(); + if (value.contains(".")) { + value = value.substring(0, value.indexOf('.')); + } + switch (pair[0].charAt(0)) { + case 't': + position.set(Position.PREFIX_TEMP + pair[0].charAt(2), Integer.parseInt(value, 16)); + break; + case 'N': + position.set("fuel" + pair[0].charAt(2), Integer.parseInt(value, 16)); + break; + case 'Q': + position.set("drivingQuality", Integer.parseInt(value, 16)); + break; + default: + break; + } + } } - remaining -= value.length() + 1; + remaining -= attribute.length() + 1; } break; default: @@ -393,7 +421,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { String type = values[index++]; - if (!type.equals("STT")) { + if (!type.equals("STT") && !type.equals("ALT")) { return null; } diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java index 90fa4aa39..6dae42ad5 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class SuntechProtocolEncoder extends StringProtocolEncoder { + public SuntechProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/SviasProtocol.java b/src/main/java/org/traccar/protocol/SviasProtocol.java index f01f28389..accfa173f 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocol.java +++ b/src/main/java/org/traccar/protocol/SviasProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ public class SviasProtocol extends BaseProtocol { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "]")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new SviasProtocolEncoder()); + pipeline.addLast(new SviasProtocolEncoder(SviasProtocol.this)); pipeline.addLast(new SviasProtocolDecoder(SviasProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java b/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java index 8bfbef119..2607d7bd1 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,9 +18,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class SviasProtocolEncoder extends StringProtocolEncoder { + public SviasProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { switch (command.getType()) { diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index ba231a635..b75addfae 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -96,6 +96,19 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); + private static final Pattern PATTERN_GPIOP = new PatternBuilder() + .text("$GPIOP,") + .number("[01]{8},") // inputs + .number("[01]{8},") // outputs + .number("d+.d+,") // adc 1 + .number("d+.d+,") // adc 2 + .number("d+.d+,") // adc 3 + .number("d+.d+,") // adc 4 + .number("(d+.d+),") // power + .number("(d+.d+)") // battery + .any() + .compile(); + private Position position = null; private Position decodeGprmc( @@ -103,7 +116,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel) && Context.getIdentityManager().lookupAttributeBoolean( - deviceSession.getDeviceId(), getProtocolName() + ".ack", false, true)) { + deviceSession.getDeviceId(), getProtocolName() + ".ack", false, false, true)) { channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); } @@ -225,6 +238,24 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeGpiop(DeviceSession deviceSession, String sentence) { + + Parser parser = new Parser(PATTERN_GPIOP, sentence); + if (!parser.matches()) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + position.set(Position.KEY_POWER, parser.nextDouble()); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + + return position; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -275,6 +306,8 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { return decodeGprma(deviceSession, sentence); } else if (sentence.startsWith("$TRCCR") && deviceSession != null) { return decodeTrccr(deviceSession, sentence); + } else if (sentence.startsWith("$GPIOP")) { + return decodeGpiop(deviceSession, sentence); } return null; diff --git a/src/main/java/org/traccar/protocol/T800xProtocol.java b/src/main/java/org/traccar/protocol/T800xProtocol.java index 85749d0cf..8b91265cb 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocol.java +++ b/src/main/java/org/traccar/protocol/T800xProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ public class T800xProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, -5, 0)); - pipeline.addLast(new T800xProtocolEncoder()); + pipeline.addLast(new T800xProtocolEncoder(T800xProtocol.this)); pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 96fb7f96a..9b146ec90 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -31,19 +31,30 @@ import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.Position; +import java.math.BigInteger; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Date; public class T800xProtocolDecoder extends BaseProtocolDecoder { + private short header = DEFAULT_HEADER; + + public short getHeader() { + return header; + } + public T800xProtocolDecoder(Protocol protocol) { super(protocol); } + public static final short DEFAULT_HEADER = 0x2323; + public static final int MSG_LOGIN = 0x01; public static final int MSG_GPS = 0x02; public static final int MSG_HEARTBEAT = 0x03; public static final int MSG_ALARM = 0x04; + public static final int MSG_NETWORK = 0x05; public static final int MSG_COMMAND = 0x81; private void sendResponse(Channel channel, short header, int type, int index, ByteBuf imei, int alarm) { @@ -91,13 +102,24 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } + private Date readDate(ByteBuf buf) { + return new DateBuilder() + .setYear(BcdUtil.readInteger(buf, 2)) + .setMonth(BcdUtil.readInteger(buf, 2)) + .setDay(BcdUtil.readInteger(buf, 2)) + .setHour(BcdUtil.readInteger(buf, 2)) + .setMinute(BcdUtil.readInteger(buf, 2)) + .setSecond(BcdUtil.readInteger(buf, 2)) + .getDate(); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; - short header = buf.readShort(); + header = buf.readShort(); int type = buf.readUnsignedByte(); buf.readUnsignedShort(); // length int index = buf.readUnsignedShort(); @@ -109,9 +131,32 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return null; } + if (type != MSG_GPS && type != MSG_ALARM) { + sendResponse(channel, header, type, index, imei, 0); + } + if (type == MSG_GPS || type == MSG_ALARM) { - return decodePosition(channel, deviceSession, buf, header, type, index, imei); + return decodePosition(channel, deviceSession, buf, type, index, imei); + + } else if (type == MSG_NETWORK) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, readDate(buf)); + + position.set(Position.KEY_OPERATOR, buf.readCharSequence( + buf.readUnsignedByte(), StandardCharsets.UTF_16LE).toString()); + position.set("networkTechnology", buf.readCharSequence( + buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString()); + position.set("networkBand", buf.readCharSequence( + buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString()); + buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII); // imsi + position.set(Position.KEY_ICCID, buf.readCharSequence( + buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString()); + + return position; } else if (type == MSG_COMMAND) { @@ -124,77 +169,77 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RESULT, buf.toString(StandardCharsets.UTF_16LE)); - sendResponse(channel, header, type, index, imei, 0); - return position; } - sendResponse(channel, header, type, index, imei, 0); - return null; } private Position decodePosition( Channel channel, DeviceSession deviceSession, - ByteBuf buf, short header, int type, int index, ByteBuf imei) { + ByteBuf buf, int type, int index, ByteBuf imei) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_INDEX, index); - buf.readUnsignedShort(); // acc on interval - buf.readUnsignedShort(); // acc off interval - buf.readUnsignedByte(); // angle compensation - buf.readUnsignedShort(); // distance compensation + if (header != 0x2727) { + + buf.readUnsignedShort(); // acc on interval + buf.readUnsignedShort(); // acc off interval + buf.readUnsignedByte(); // angle compensation + buf.readUnsignedShort(); // distance compensation - position.set(Position.KEY_RSSI, BitUtil.to(buf.readUnsignedShort(), 7)); + position.set(Position.KEY_RSSI, BitUtil.to(buf.readUnsignedShort(), 7)); + + } int status = buf.readUnsignedByte(); position.set(Position.KEY_SATELLITES, BitUtil.to(status, 5)); - buf.readUnsignedByte(); // gsensor manager status - buf.readUnsignedByte(); // other flags - buf.readUnsignedByte(); // heartbeat - buf.readUnsignedByte(); // relay status - buf.readUnsignedShort(); // drag alarm setting - - int io = buf.readUnsignedShort(); - position.set(Position.KEY_IGNITION, BitUtil.check(io, 14)); - position.set("ac", BitUtil.check(io, 13)); - for (int i = 0; i <= 2; i++) { - position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(io, 7 + i)); - } + if (header != 0x2727) { - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); + buf.readUnsignedByte(); // gsensor manager status + buf.readUnsignedByte(); // other flags + buf.readUnsignedByte(); // heartbeat + buf.readUnsignedByte(); // relay status + buf.readUnsignedShort(); // drag alarm setting + + int io = buf.readUnsignedShort(); + position.set(Position.KEY_IGNITION, BitUtil.check(io, 14)); + position.set("ac", BitUtil.check(io, 13)); + for (int i = 0; i <= 2; i++) { + position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(io, 7 + i)); + } + + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); + + } int alarm = buf.readUnsignedByte(); position.set(Position.KEY_ALARM, decodeAlarm(alarm)); - buf.readUnsignedByte(); // reserved + if (header != 0x2727) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + buf.readUnsignedByte(); // reserved - int battery = BcdUtil.readInteger(buf, 2); - if (battery == 0) { - battery = 100; - } - position.set(Position.KEY_BATTERY, battery); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - DateBuilder dateBuilder = new DateBuilder() - .setYear(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setDay(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); + int battery = BcdUtil.readInteger(buf, 2); + if (battery == 0) { + battery = 100; + } + position.set(Position.KEY_BATTERY, battery); + + } if (BitUtil.check(status, 6)) { position.setValid(!BitUtil.check(status, 7)); - position.setTime(dateBuilder.getDate()); + position.setTime(readDate(buf)); position.setAltitude(buf.readFloatLE()); position.setLongitude(buf.readFloatLE()); position.setLatitude(buf.readFloatLE()); @@ -203,7 +248,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } else { - getLastLocation(position, dateBuilder.getDate()); + getLastLocation(position, readDate(buf)); int mcc = buf.readUnsignedShortLE(); int mnc = buf.readUnsignedShortLE(); @@ -219,8 +264,46 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } - if (buf.readableBytes() >= 2) { + if (header == 0x2727) { + + byte[] accelerationBytes = new byte[5]; + buf.readBytes(accelerationBytes); + long acceleration = new BigInteger(accelerationBytes).longValue(); + double accelerationZ = BitUtil.between(acceleration, 8, 15) + BitUtil.between(acceleration, 4, 8) * 0.1; + if (!BitUtil.check(acceleration, 15)) { + accelerationZ = -accelerationZ; + } + double accelerationY = BitUtil.between(acceleration, 20, 27) + BitUtil.between(acceleration, 16, 20) * 0.1; + if (!BitUtil.check(acceleration, 27)) { + accelerationY = -accelerationY; + } + double accelerationX = BitUtil.between(acceleration, 28, 32) + BitUtil.between(acceleration, 32, 39) * 0.1; + if (!BitUtil.check(acceleration, 39)) { + accelerationX = -accelerationX; + } + position.set(Position.KEY_G_SENSOR, "[" + accelerationX + "," + accelerationY + "," + accelerationZ + "]"); + + position.set(Position.KEY_BATTERY_LEVEL, BcdUtil.readInteger(buf, 2)); + position.set(Position.KEY_DEVICE_TEMP, (int) buf.readByte()); + position.set("lightSensor", BcdUtil.readInteger(buf, 2) * 0.1); + position.set(Position.KEY_BATTERY, BcdUtil.readInteger(buf, 2) * 0.1); + position.set("solarPanel", BcdUtil.readInteger(buf, 2) * 0.1); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + + int inputStatus = buf.readUnsignedShort(); + position.set(Position.KEY_IGNITION, BitUtil.check(inputStatus, 2)); + position.set(Position.KEY_RSSI, BitUtil.between(inputStatus, 4, 11)); + + buf.readUnsignedShort(); // ignition on upload interval + buf.readUnsignedInt(); // ignition off upload interval + buf.readUnsignedByte(); // angle upload interval + buf.readUnsignedShort(); // distance upload interval + buf.readUnsignedByte(); // heartbeat + + } else if (buf.readableBytes() >= 2) { + position.set(Position.KEY_POWER, BcdUtil.readInteger(buf, 4) * 0.01); + } sendResponse(channel, header, type, index, imei, alarm); diff --git a/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java b/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java index 34f30b147..74587c8b1 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,11 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.DataConverter; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.charset.StandardCharsets; @@ -29,12 +31,15 @@ public class T800xProtocolEncoder extends BaseProtocolEncoder { public static final int MODE_BROADCAST = 0x02; public static final int MODE_FORWARD = 0x03; - private ByteBuf encodeContent(Command command, String content) { + public T800xProtocolEncoder(Protocol protocol) { + super(protocol); + } + + private ByteBuf encodeContent(Command command, short header, String content) { ByteBuf buf = Unpooled.buffer(); - buf.writeByte('%'); - buf.writeByte('%'); + buf.writeShort(header); buf.writeByte(T800xProtocolDecoder.MSG_COMMAND); buf.writeShort(7 + 8 + 1 + content.length()); buf.writeShort(1); // serial number @@ -46,11 +51,16 @@ public class T800xProtocolEncoder extends BaseProtocolEncoder { } @Override - protected Object encodeCommand(Command command) { + protected Object encodeCommand(Channel channel, Command command) { + + short header = T800xProtocolDecoder.DEFAULT_HEADER; + if (channel != null) { + header = channel.pipeline().get(T800xProtocolDecoder.class).getHeader(); + } switch (command.getType()) { case Command.TYPE_CUSTOM: - return encodeContent(command, command.getString(Command.KEY_DATA)); + return encodeContent(command, header, command.getString(Command.KEY_DATA)); default: return null; } diff --git a/src/main/java/org/traccar/protocol/TechTltProtocol.java b/src/main/java/org/traccar/protocol/TechTltProtocol.java index 69a12532c..0cffb452d 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocol.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocol.java @@ -29,7 +29,7 @@ public class TechTltProtocol extends BaseProtocol { protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Ardi01ProtocolDecoder(TechTltProtocol.this)); + pipeline.addLast(new TechTltProtocolDecoder(TechTltProtocol.this)); } }); } diff --git a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java index bad289060..17f5c80fa 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java @@ -35,6 +35,15 @@ public class TechTltProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + private static final Pattern PATTERN_STATUS = new PatternBuilder() + .number("(d+),") // id + .text("INFOGPRS,") + .number("V Bat=(d+.d),") // battery + .number("TEMP=(d+),") // temperature + .expression("[^,]*,") + .number("(d+)") // rssi + .compile(); + private static final Pattern PATTERN_POSITION = new PatternBuilder() .number("(d+)") // id .text("*POS=Y,") @@ -52,11 +61,33 @@ public class TechTltProtocolDecoder extends BaseProtocolDecoder { .number("(d+)") // cid .compile(); - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + private Position decodeStatus(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_POSITION, (String) msg); + Parser parser = new Parser(PATTERN_STATUS, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + position.set(Position.KEY_BATTERY, parser.nextDouble()); + position.set(Position.KEY_DEVICE_TEMP, parser.nextInt()); + position.set(Position.KEY_RSSI, parser.nextInt()); + + return position; + } + + private Position decodeLocation(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_POSITION, sentence); if (!parser.matches()) { return null; } @@ -84,4 +115,18 @@ public class TechTltProtocolDecoder extends BaseProtocolDecoder { return position; } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = ((String) msg).trim(); + if (sentence.contains("INFO")) { + return decodeStatus(channel, remoteAddress, sentence); + } else if (sentence.contains("POS")) { + return decodeLocation(channel, remoteAddress, sentence); + } else { + return null; + } + } + } diff --git a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java index 6d5e8f21e..457687b2e 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,8 +42,8 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { .number("(dd)(dd)(dd)") // date (ddmmyy) .number("(dd)(dd)(dd),") // time (hhmmss) .groupBegin() - .number("(ddd)(dd)(dddd),") // longitude - .number("(dd)(dd)(dddd),") // latitude + .number("(-?d{9}),") // longitude + .number("(-?d{8}),") // latitude .or() .number("(-?d+),") // longitude .number("(-?d+),") // latitude @@ -88,17 +88,16 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - int event = parser.nextInt(0); + int event = parser.nextInt(); position.set(Position.KEY_EVENT, event); - position.set(Position.KEY_ALARM, decodeAlarm(event)); if (event == 11) { @@ -109,25 +108,22 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - if (parser.hasNext(6)) { - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); + if (parser.hasNext(2)) { + position.setLongitude(parser.nextDouble() / 1000000); + position.setLatitude(parser.nextDouble() / 1000000); } if (parser.hasNext(2)) { - position.setLongitude(parser.nextDouble(0) / 10000); - position.setLatitude(parser.nextDouble(0) / 10000); + position.setLongitude(parser.nextDouble() / 10000); + position.setLatitude(parser.nextDouble() / 10000); } - position.setValid(parser.nextInt(0) != 1); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - - if (parser.hasNext()) { - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - } + position.setValid(parser.nextInt() != 1); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); - position.set(Position.KEY_BATTERY, parser.nextInt(0)); + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_BATTERY, parser.nextInt()); return position; } diff --git a/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java index 4d4d79d8d..c30fee6e3 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,12 +29,14 @@ public class TeltonikaFrameDecoder extends BaseFrameDecoder { protected Object decode( ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - // Check minimum length + while (buf.isReadable() && buf.getByte(buf.readerIndex()) == (byte) 0xff) { + buf.skipBytes(1); + } + if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { return null; } - // Read packet int length = buf.getUnsignedShort(buf.readerIndex()); if (length > 0) { if (buf.readableBytes() >= (length + 2)) { diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java index eef9662d7..5817b86be 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,14 +29,14 @@ public class TeltonikaProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new TeltonikaFrameDecoder()); - pipeline.addLast(new TeltonikaProtocolEncoder()); + pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this)); pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false)); } }); addServer(new TrackerServer(true, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new TeltonikaProtocolEncoder()); + pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this)); pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, true)); } }); diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 485df833a..c634d2438 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -157,7 +157,19 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } if (readable) { - position.set(Position.KEY_RESULT, buf.readSlice(length).toString(StandardCharsets.US_ASCII)); + String data = buf.readSlice(length).toString(StandardCharsets.US_ASCII).trim(); + if (data.startsWith("UUUUww") && data.endsWith("SSS")) { + String[] values = data.substring(6, data.length() - 4).split(";"); + for (int i = 0; i < 8; i++) { + position.set("axle" + (i + 1), Double.parseDouble(values[i])); + } + position.set("loadTruck", Double.parseDouble(values[8])); + position.set("loadTrailer", Double.parseDouble(values[9])); + position.set("totalTruck", Double.parseDouble(values[10])); + position.set("totalTrailer", Double.parseDouble(values[11])); + } else { + position.set(Position.KEY_RESULT, data); + } } else { position.set(Position.KEY_RESULT, ByteBufUtil.hexDump(buf.readSlice(length))); } diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolEncoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolEncoder.java index 5380cf3a0..8a614618a 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolEncoder.java @@ -19,6 +19,7 @@ import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; import org.traccar.model.Command; +import org.traccar.Protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; @@ -27,6 +28,10 @@ import java.nio.charset.StandardCharsets; public class TeltonikaProtocolEncoder extends BaseProtocolEncoder { + public TeltonikaProtocolEncoder(Protocol protocol) { + super(protocol); + } + private ByteBuf encodeContent(byte[] content) { ByteBuf buf = Unpooled.buffer(); diff --git a/src/main/java/org/traccar/protocol/Tk103Protocol.java b/src/main/java/org/traccar/protocol/Tk103Protocol.java index fa83133e2..ff0bedfb7 100644 --- a/src/main/java/org/traccar/protocol/Tk103Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk103Protocol.java @@ -1,6 +1,6 @@ /* * Copyright 2017 Christoph Krey (c@ckrey.de) - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ public class Tk103Protocol extends BaseProtocol { pipeline.addLast(new Tk103FrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Tk103ProtocolEncoder()); + pipeline.addLast(new Tk103ProtocolEncoder(Tk103Protocol.this)); pipeline.addLast(new Tk103ProtocolDecoder(Tk103Protocol.this)); } }); @@ -60,7 +60,7 @@ public class Tk103Protocol extends BaseProtocol { protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); - pipeline.addLast(new Tk103ProtocolEncoder()); + pipeline.addLast(new Tk103ProtocolEncoder(Tk103Protocol.this)); pipeline.addLast(new Tk103ProtocolDecoder(Tk103Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java index 98edc8cb5..a8aa84105 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java @@ -1,6 +1,6 @@ /* * Copyright 2017 Christoph Krey (c@ckrey.de) - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,19 @@ package org.traccar.protocol; import org.traccar.Context; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class Tk103ProtocolEncoder extends StringProtocolEncoder { private final boolean forceAlternative; - public Tk103ProtocolEncoder() { + public Tk103ProtocolEncoder(Protocol protocol) { + super(protocol); this.forceAlternative = false; } - public Tk103ProtocolEncoder(boolean forceAlternative) { + public Tk103ProtocolEncoder(Protocol protocol, boolean forceAlternative) { + super(protocol); this.forceAlternative = forceAlternative; } @@ -40,7 +43,7 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { protected Object encodeCommand(Command command) { boolean alternative = forceAlternative || Context.getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), "tk103.alternative", false, true); + command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); initDevicePassword(command, "123456"); diff --git a/src/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java index 66e1ec4f1..f8cda8358 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocol.java +++ b/src/main/java/org/traccar/protocol/TotemProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ public class TotemProtocol extends BaseProtocol { pipeline.addLast(new TotemFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new TotemProtocolEncoder()); + pipeline.addLast(new TotemProtocolEncoder(TotemProtocol.this)); pipeline.addLast(new TotemProtocolDecoder(TotemProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java index b5049859d..3bbb92031 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java @@ -1,6 +1,6 @@ /* * Copyright 2015 Irving Gonzalez - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class TotemProtocolEncoder extends StringProtocolEncoder { + public TotemProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java b/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java index aaaaccb60..e4c94dc77 100644 --- a/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ public class TramigoFrameDecoder extends BaseFrameDecoder { length = buf.getUnsignedShort(buf.readerIndex() + 6); } - if (length >= buf.readableBytes()) { + if (length <= buf.readableBytes()) { return buf.readRetainedSlice(length); } diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java index b63385187..05312b820 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,8 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .expression("[A-Z]{2,3}") - .number("APdd") + .expression("[A-Z]P") + .number("dd") .number("(dd)(dd)(dd)") // date (yymmdd) .expression("([AV])") // validity .number("(dd)(dd.d+)") // latitude @@ -57,7 +58,8 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(ddd)") // battery .number("(d)") // acc .number("(dd)") // arm status - .number("(dd),") // working mode + .number("(dd)") // working mode + .number("(?:[0-2]{3})?,") .number("(d+),") // mcc .number("(d+),") // mnc .number("(d+),") // lac @@ -181,7 +183,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type.equals("AP01") || type.equals("AP10")) { + } else if (type.equals("AP01") || type.equals("AP10") || type.equals("YP03")) { Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 87b44a4b2..4f6854098 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; +import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.Position; @@ -67,7 +68,17 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { return false; } - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + if (hardware == 0x413) { + buf.readUnsignedByte(); // status + } else { + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + } + + if (hardware == 0x413) { + position.setFixTime(new DateBuilder() + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate()); + } double lat; double lon; @@ -80,25 +91,39 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { lon = buf.readUnsignedInt() / 100000.0 / 60.0; } - position.setFixTime(new DateBuilder() - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate()); + if (hardware == 0x413) { - position.setSpeed(buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_HDOP, buf.readUnsignedShort() * 0.1); - position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium()); + position.setAltitude(buf.readUnsignedShort()); + position.setCourse(buf.readUnsignedShort()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); + + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + + } else { + + position.setFixTime(new DateBuilder() + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate()); + + position.setSpeed(buf.readUnsignedShort() * 0.01); + + position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium()); + + int flags = buf.readUnsignedShort(); + position.setCourse(BitUtil.to(flags, 9)); + if (!BitUtil.check(flags, 10)) { + lat = -lat; + } + position.setLatitude(lat); + if (BitUtil.check(flags, 9)) { + lon = -lon; + } + position.setLongitude(lon); + position.setValid(BitUtil.check(flags, 11)); - int flags = buf.readUnsignedShort(); - position.setCourse(BitUtil.to(flags, 9)); - if (!BitUtil.check(flags, 10)) { - lat = -lat; - } - position.setLatitude(lat); - if (BitUtil.check(flags, 9)) { - lon = -lon; } - position.setLongitude(lon); - position.setValid(BitUtil.check(flags, 11)); buf.readerIndex(blockEnd); diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java index 0a2a59e23..7fec0bf8b 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -237,12 +237,13 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { case DATA_GPS: hasLocation = true; - position.setValid(true); position.setLatitude(buf.readInt() / 1000000.0); position.setLongitude(buf.readInt() / 1000000.0); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); position.setCourse(buf.readUnsignedShort()); - position.set(Position.KEY_HDOP, buf.readUnsignedShort()); + int hdop = buf.readUnsignedShort(); + position.setValid(hdop < 9999); + position.set(Position.KEY_HDOP, hdop * 0.01); break; case DATA_LBS: diff --git a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java index dc7a9200d..873b22006 100644 --- a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -89,6 +89,13 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { } } + private String decodeAlarm(int alarm) { + if (BitUtil.check(alarm, 2)) { + return Position.ALARM_TAMPERING; + } + return null; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -160,9 +167,25 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { position.setSpeed( Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)) * 0.1); break; + case 'G': + position.setAltitude( + Integer.parseInt(data.readSlice(6).toString(StandardCharsets.US_ASCII)) * 0.1); + break; case 'K': position.set("statusExtended", data.toString(StandardCharsets.US_ASCII)); break; + case 'M': + position.set(Position.KEY_BATTERY_LEVEL, + Integer.parseInt(data.readSlice(3).toString(StandardCharsets.US_ASCII)) * 0.1); + break; + case 'N': + position.set(Position.KEY_RSSI, + Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); + break; + case 'O': + position.set(Position.KEY_SATELLITES, + Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); + break; case 'P': if (data.readableBytes() >= 16) { position.setNetwork(new Network(CellTower.from( @@ -188,25 +211,53 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { case 'S': position.set("obdTraffic", ByteBufUtil.hexDump(data)); break; - case 'T': - position.set(Position.KEY_BATTERY_LEVEL, - Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); - break; case 'V': position.set(Position.KEY_POWER, Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)) * 0.1); break; + case 'W': + position.set(Position.KEY_ALARM, + decodeAlarm(Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII)))); + break; + case 'X': + Network network = new Network(); + int mcc = 0, mnc = 0; + String[] cells = data.toString(StandardCharsets.US_ASCII).split(";"); + if (!cells[0].startsWith("(")) { + for (int i = 0; i < cells.length; i++) { + String[] values = cells[i].split(","); + int index = 0; + if (i == 0) { + mcc = Integer.parseInt(values[index++]); + mnc = Integer.parseInt(values[index++]); + } + network.addCellTower(CellTower.from( + mcc, mnc, + Integer.parseInt(values[index++]), + Integer.parseInt(values[index++]), + Integer.parseInt(values[index]))); + } + position.setNetwork(network); + } + break; + case 'Y': + position.set(Position.KEY_POWER, + Integer.parseInt(data.readSlice(5).toString(StandardCharsets.US_ASCII)) * 0.001); + break; default: break; } } - if (position.getLatitude() != 0 && position.getLongitude() != 0) { - return position; + if (position.getLatitude() == 0 || position.getLongitude() == 0) { + if (position.getAttributes().isEmpty()) { + return null; + } + getLastLocation(position, position.getDeviceTime()); } - return null; + return position; } } diff --git a/src/main/java/org/traccar/protocol/WatchProtocol.java b/src/main/java/org/traccar/protocol/WatchProtocol.java index fe285e70d..6dc3bf9fb 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocol.java +++ b/src/main/java/org/traccar/protocol/WatchProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ public class WatchProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new WatchFrameDecoder()); - pipeline.addLast(new WatchProtocolEncoder()); + pipeline.addLast(new WatchProtocolEncoder(WatchProtocol.this)); pipeline.addLast(new WatchProtocolDecoder(WatchProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 70b207e9b..0647afdee 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -249,8 +249,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { } } - } else if (type.equals("UD") || type.equals("UD2") || type.equals("UD3") - || type.equals("AL") || type.equals("WT")) { + } else if (type.startsWith("UD") || type.equals("AL") || type.equals("WT")) { Position position = decodePosition(deviceSession, buf.toString(StandardCharsets.US_ASCII)); @@ -267,7 +266,10 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, id, index, "TKQ"); - } else if (type.equals("PULSE") || type.equals("heart") || type.equals("bphrt")) { + } else if (type.equalsIgnoreCase("PULSE") + || type.equalsIgnoreCase("HEART") + || type.equalsIgnoreCase("BLOOD") + || type.equalsIgnoreCase("BPHRT")) { if (buf.isReadable()) { @@ -279,11 +281,14 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { String[] values = buf.toString(StandardCharsets.US_ASCII).split(","); int valueIndex = 0; - if (type.equals("bphrt")) { + if (type.equalsIgnoreCase("BPHRT") || type.equalsIgnoreCase("BLOOD")) { position.set("pressureHigh", values[valueIndex++]); position.set("pressureLow", values[valueIndex++]); } - position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[valueIndex])); + + if (valueIndex <= values.length - 1) { + position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[valueIndex])); + } return position; diff --git a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java index 264aec81f..b433dfd2a 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import io.netty.channel.Channel; import org.traccar.StringProtocolEncoder; import org.traccar.helper.DataConverter; import org.traccar.model.Command; +import org.traccar.Protocol; import java.nio.charset.StandardCharsets; import java.text.DecimalFormat; @@ -32,6 +33,10 @@ import java.util.TimeZone; public class WatchProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { + public WatchProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override public String formatValue(String key, Object value) { if (key.equals(Command.KEY_TIMEZONE)) { diff --git a/src/main/java/org/traccar/protocol/WialonProtocol.java b/src/main/java/org/traccar/protocol/WialonProtocol.java index 06b54dceb..fd183dd2c 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocol.java +++ b/src/main/java/org/traccar/protocol/WialonProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,14 +38,31 @@ public class WialonProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); - pipeline.addLast(new StringEncoder()); boolean utf8 = Context.getConfig().getBoolean(getName() + ".utf8"); if (utf8) { + pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8)); pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); } else { + pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); } - pipeline.addLast(new WialonProtocolEncoder()); + pipeline.addLast(new WialonProtocolEncoder(WialonProtocol.this)); + pipeline.addLast(new WialonProtocolDecoder(WialonProtocol.this)); + } + }); + addServer(new TrackerServer(true, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); + boolean utf8 = Context.getConfig().getBoolean(getName() + ".utf8"); + if (utf8) { + pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8)); + pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); + } else { + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + } + pipeline.addLast(new WialonProtocolEncoder(WialonProtocol.this)); pipeline.addLast(new WialonProtocolDecoder(WialonProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 42ff3177e..8488ca2d1 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -38,6 +38,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + private static final Pattern PATTERN_ANY = new PatternBuilder() + .expression("([^#]*)?") // imei + .text("#") // start byte + .expression("([^#]+)") // type + .text("#") // separator + .expression("(.*)") // message + .compile(); + private static final Pattern PATTERN = new PatternBuilder() .number("(dd)(dd)(dd);") // date (ddmmyy) .number("(dd)(dd)(dd);") // time (hhmmss) @@ -62,7 +70,8 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { private void sendResponse(Channel channel, SocketAddress remoteAddress, String type, Integer number) { if (channel != null) { StringBuilder response = new StringBuilder("#A"); - response.append(type.substring(1)); + response.append(type); + response.append("#"); if (number != null) { response.append(number); } @@ -71,9 +80,9 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } } - private Position decodePosition(Channel channel, SocketAddress remoteAddress, String substring) { + private Position decodePosition(Channel channel, SocketAddress remoteAddress, String id, String substring) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession == null) { return null; } @@ -135,12 +144,20 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String sentence = (String) msg; - String type = sentence.substring(0, sentence.indexOf('#', 1) + 1); + + Parser parser = new Parser(PATTERN_ANY, sentence); + if (!parser.matches()) { + return null; + } + + String id = parser.next(); + String type = parser.next(); + String data = parser.next(); switch (type) { - case "#L#": - String[] values = sentence.substring(3).split(";"); + case "L": + String[] values = data.split(";"); String imei = values[0].indexOf('.') >= 0 ? values[1] : values[0]; DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); @@ -149,14 +166,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } break; - case "#P#": + case "P": sendResponse(channel, remoteAddress, type, null); // heartbeat break; - case "#D#": - case "#SD#": + case "D": + case "SD": Position position = decodePosition( - channel, remoteAddress, sentence.substring(sentence.indexOf('#', 1) + 1)); + channel, remoteAddress, id, data); if (position != null) { sendResponse(channel, remoteAddress, type, 1); @@ -164,12 +181,12 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } break; - case "#B#": - String[] messages = sentence.substring(sentence.indexOf('#', 1) + 1).split("\\|"); + case "B": + String[] messages = data.split("\\|"); List<Position> positions = new LinkedList<>(); for (String message : messages) { - position = decodePosition(channel, remoteAddress, message); + position = decodePosition(channel, remoteAddress, id, message); if (position != null) { position.set(Position.KEY_ARCHIVE, true); positions.add(position); @@ -182,14 +199,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } break; - case "#M#": - deviceSession = getDeviceSession(channel, remoteAddress); + case "M": + deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession != null) { position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, new Date()); position.setValid(false); - position.set(Position.KEY_RESULT, sentence.substring(sentence.indexOf('#', 1) + 1)); + position.set(Position.KEY_RESULT, data); sendResponse(channel, remoteAddress, type, 1); return position; } diff --git a/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java b/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java index 9ff1631eb..c45edf00d 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,9 +18,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class WialonProtocolEncoder extends StringProtocolEncoder { + public WialonProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { switch (command.getType()) { diff --git a/src/main/java/org/traccar/protocol/WondexProtocol.java b/src/main/java/org/traccar/protocol/WondexProtocol.java index 8c6283d66..035dd9160 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocol.java +++ b/src/main/java/org/traccar/protocol/WondexProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import io.netty.handler.codec.string.StringEncoder; public class WondexProtocol extends BaseProtocol { public WondexProtocol() { - setTextCommandEncoder(new WondexProtocolEncoder()); setSupportedCommands( Command.TYPE_GET_DEVICE_STATUS, Command.TYPE_GET_MODEM_STATUS, @@ -33,12 +32,13 @@ public class WondexProtocol extends BaseProtocol { Command.TYPE_POSITION_SINGLE, Command.TYPE_GET_VERSION, Command.TYPE_IDENTIFICATION); + setTextCommandEncoder(new WondexProtocolEncoder(this)); addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new WondexFrameDecoder()); pipeline.addLast(new StringEncoder()); - pipeline.addLast(new WondexProtocolEncoder()); + pipeline.addLast(new WondexProtocolEncoder(WondexProtocol.this)); pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this)); } }); @@ -46,7 +46,7 @@ public class WondexProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new StringEncoder()); - pipeline.addLast(new WondexProtocolEncoder()); + pipeline.addLast(new WondexProtocolEncoder(WondexProtocol.this)); pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java index f9e8eeb9b..e9bb23d15 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class WondexProtocolEncoder extends StringProtocolEncoder { + public WondexProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/XexunProtocol.java b/src/main/java/org/traccar/protocol/XexunProtocol.java index 0005270fb..401844e7b 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocol.java +++ b/src/main/java/org/traccar/protocol/XexunProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ public class XexunProtocol extends BaseProtocol { } pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new XexunProtocolEncoder()); + pipeline.addLast(new XexunProtocolEncoder(XexunProtocol.this)); pipeline.addLast(new XexunProtocolDecoder(XexunProtocol.this, full)); } }); diff --git a/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java b/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java index 515cfbbd0..fc849fe15 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class XexunProtocolEncoder extends StringProtocolEncoder { + public XexunProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/XirgoProtocol.java b/src/main/java/org/traccar/protocol/XirgoProtocol.java index 4979fda5d..1be5b6c4b 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocol.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ public class XirgoProtocol extends BaseProtocol { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new XirgoProtocolEncoder()); + pipeline.addLast(new XirgoProtocolEncoder(XirgoProtocol.this)); pipeline.addLast(new XirgoProtocolDecoder(XirgoProtocol.this)); } }); @@ -44,7 +44,7 @@ public class XirgoProtocol extends BaseProtocol { protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new XirgoProtocolEncoder()); + pipeline.addLast(new XirgoProtocolEncoder(XirgoProtocol.this)); pipeline.addLast(new XirgoProtocolDecoder(XirgoProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java index 08809307f..4d0cc314b 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java @@ -266,7 +266,7 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { position.setValid(Integer.parseInt(values[i]) == 3); break; case "SI": - position.set("iccid", values[i]); + position.set(Position.KEY_ICCID, values[i]); break; case "IG": int ignition = Integer.parseInt(values[i]); diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java index dd5e30cca..aa85e9e0e 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,14 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class XirgoProtocolEncoder extends StringProtocolEncoder { + public XirgoProtocolEncoder(Protocol protocol) { + super(protocol); + } + @Override protected Object encodeCommand(Command command) { diff --git a/src/main/java/org/traccar/protocol/Xrb28Protocol.java b/src/main/java/org/traccar/protocol/Xrb28Protocol.java index b1f1c34fb..5d8af418b 100644 --- a/src/main/java/org/traccar/protocol/Xrb28Protocol.java +++ b/src/main/java/org/traccar/protocol/Xrb28Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ public class Xrb28Protocol extends BaseProtocol { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder(StandardCharsets.ISO_8859_1)); pipeline.addLast(new StringDecoder()); - pipeline.addLast(new Xrb28ProtocolEncoder()); + pipeline.addLast(new Xrb28ProtocolEncoder(Xrb28Protocol.this)); pipeline.addLast(new Xrb28ProtocolDecoder(Xrb28Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java index 617639312..3e69af329 100644 --- a/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,14 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolEncoder; import org.traccar.model.Command; +import org.traccar.Protocol; public class Xrb28ProtocolEncoder extends BaseProtocolEncoder { + public Xrb28ProtocolEncoder(Protocol protocol) { + super(protocol); + } + private String formatCommand(Command command, String content) { return String.format("\u00ff\u00ff*SCOS,OM,%s,%s#\n", getUniqueId(command.getDeviceId()), content); } diff --git a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java index 819011a50..c132f194b 100644 --- a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,7 +59,7 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { 0x26, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x57, 0x58, 0x59, 0x5a, 0x6b, 0x6f, 0x7A, 0x7B, 0x7C, 0x7d, 0x7E, 0x7F, 0x80, 0x81, 0x82, - 0x83, 0x84, 0x85, 0x86 + 0x83, 0x84, 0x85, 0x86, 0xc8 }; int[] l4 = { 0x03, 0x06, 0x07, 0x08, 0x0e, 0x0f, 0x10, 0x11, @@ -80,12 +80,13 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { TAG_LENGTH_MAP.put(i, 4); } TAG_LENGTH_MAP.put(0x95, 24); + TAG_LENGTH_MAP.put(0xD0, 21); } private static int getTagLength(int tag) { Integer length = TAG_LENGTH_MAP.get(tag); if (length == null) { - throw new IllegalArgumentException("Unknown tag: " + tag); + throw new IllegalArgumentException(String.format("Unknown tag: 0x%02X", tag)); } return length; } @@ -93,7 +94,7 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { private Map<Short, byte[]> formats = new HashMap<>(); public void setConfig(String configString) { - Pattern pattern = Pattern.compile(":wycfg pcr\\[\\d+\\] ([0-9a-fA-F]{2})[0-9a-fA-F]{2}([0-9a-fA-F]+)"); + Pattern pattern = Pattern.compile(":wycfg pcr\\[\\d+] ([0-9a-fA-F]{2})[0-9a-fA-F]{2}([0-9a-fA-F]+)"); Matcher matcher = pattern.matcher(configString); while (matcher.find()) { formats.put(Short.parseShort(matcher.group(1), 16), DataConverter.parseHex(matcher.group(2))); @@ -119,7 +120,8 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); - for (byte tag : format) { + for (byte b : format) { + int tag = b & 0xFF; switch (tag) { case 0x03: DeviceSession deviceSession = getDeviceSession( @@ -177,6 +179,14 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { case 0x65: position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII)); break; + case 0x6C: + buf.readUnsignedByte(); // mil + int ecuCount = buf.readUnsignedByte(); + for (int i = 0; i < ecuCount; i++) { + buf.readUnsignedByte(); // ecu id + buf.skipBytes(buf.readUnsignedByte() * 6); + } + break; case 0x73: position.set(Position.KEY_VERSION_FW, buf.readSlice(16).toString(StandardCharsets.US_ASCII).trim()); break; diff --git a/src/main/java/org/traccar/reports/Stops.java b/src/main/java/org/traccar/reports/Stops.java index 98c9cef00..2036b0641 100644 --- a/src/main/java/org/traccar/reports/Stops.java +++ b/src/main/java/org/traccar/reports/Stops.java @@ -43,7 +43,7 @@ public final class Stops { private static Collection<StopReport> detectStops(long deviceId, Date from, Date to) throws SQLException { boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); + .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java index 9810424d8..6d179a873 100644 --- a/src/main/java/org/traccar/reports/Summary.java +++ b/src/main/java/org/traccar/reports/Summary.java @@ -61,7 +61,7 @@ public final class Summary { result.setMaxSpeed(position.getSpeed()); } boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); + .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); result.setDistance(ReportUtils.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); result.setAverageSpeed(speedSum / positions.size()); result.setSpentFuel(ReportUtils.calculateFuel(firstPosition, previousPosition)); diff --git a/src/main/java/org/traccar/reports/Trips.java b/src/main/java/org/traccar/reports/Trips.java index 3cda65553..7c0cd6921 100644 --- a/src/main/java/org/traccar/reports/Trips.java +++ b/src/main/java/org/traccar/reports/Trips.java @@ -42,7 +42,7 @@ public final class Trips { private static Collection<TripReport> detectTrips(long deviceId, Date from, Date to) throws SQLException { boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true); + .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); diff --git a/src/test/java/org/traccar/TestIdentityManager.java b/src/test/java/org/traccar/TestIdentityManager.java index 0f7405dbd..af5dd22df 100644 --- a/src/test/java/org/traccar/TestIdentityManager.java +++ b/src/test/java/org/traccar/TestIdentityManager.java @@ -30,6 +30,11 @@ public final class TestIdentityManager implements IdentityManager { } @Override + public String getDevicePassword(long id, String protocol, String defaultPassword) { + return defaultPassword; + } + + @Override public Position getLastPosition(long deviceId) { return null; } @@ -41,31 +46,31 @@ public final class TestIdentityManager implements IdentityManager { @Override public boolean lookupAttributeBoolean( - long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) { + long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig) { return defaultValue; } @Override public String lookupAttributeString( - long deviceId, String attributeName, String defaultValue, boolean lookupConfig) { + long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig) { return "alarm,result"; } @Override public int lookupAttributeInteger( - long deviceId, String attributeName, int defaultValue, boolean lookupConfig) { + long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig) { return defaultValue; } @Override public long lookupAttributeLong( - long deviceId, String attributeName, long defaultValue, boolean lookupConfig) { + long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig) { return defaultValue; } @Override public double lookupAttributeDouble( - long deviceId, String attributeName, double defaultValue, boolean lookupConfig) { + long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig) { return defaultValue; } diff --git a/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java index cb0a31ceb..fd6214c57 100644 --- a/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) * Copyright 2017 Anatoliy Golubev (darth.naihil@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,7 +27,7 @@ public class AdmProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - AdmProtocolEncoder encoder = new AdmProtocolEncoder(); + AdmProtocolEncoder encoder = new AdmProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/AquilaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AquilaProtocolDecoderTest.java index 793b2c646..489024ed5 100644 --- a/src/test/java/org/traccar/protocol/AquilaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AquilaProtocolDecoderTest.java @@ -51,29 +51,4 @@ public class AquilaProtocolDecoderTest extends ProtocolTest { } - @Test - public void testDecodeB() throws Exception { - - AquilaProtocolDecoder decoder = new AquilaProtocolDecoder(null); - - verifyPosition(decoder, text( - "$Header,nliven,EMR,861693034634154,NM,09112017155133,A,12.976495,N,77.549713,E,906.0,0.0,23,G,KA01I2000,+919844098440*4B")); - - verifyPosition(decoder, text( - "$EPB,iTriangle1,EMR,864495034445822,SP,03082018110730,A,22.829292,N,75.935806,E,543.0,0.0,0,G,KA01G1234,+9164061023*13")); - - verifyPosition(decoder, text( - "$Header,iTriangle,1_37T02B0164MAIS_2,NR,1,L,864495034490141,KA01I2000,1,19042018,102926,22.846401,N,75.948952,E,0.0,311,5,578.0,3.80,3.67,AirTel,0,1,12.5,4.3,1,C,14,404,93,0456,16db,29,ebd8,0458,28,3843,18ab,25,072e,18ab,22,35da,0458,0000,00,031181,0.0,0.0,0,()*34")); - - verifyPosition(decoder, text( - "$Header,nliven,1_37T02B0164MAIS,BR,6,L,861693034634154,KA01I2000,1,09112017,160702,12.976593,N,77.549782,E,25.1,344,15,911.0,1.04,0.68,Airtel,1,1,11.8,3.8,1,C,24,404,45,61b4,9ad9,31,9adb,61b4,35,ffff,0000,33,ffff,0000,31,ffff,0000,0001,00,000014,0.0,0.1,4,()*1E")); - - verifyPosition(decoder, text( - "$Header,iTriangle,1_37T02B0164MAIS_2,NR,1,L,864495034490141,KA01I2000,1,31032018,122247,22.845999,N,75.949005,E,0.0,44,16,545.0,1.19,0.65,AirTel,1,1,12.0,4.3,0,C,13,404,93,0456,16db,27,16dd,0456,22,3843,18ab,19,ebd8,0458,14,072c,18ab,0101,00,003735,0.0,0.0,0,()*48")); - - verifyNull(decoder, text( - "$Header,nliven,KA01I2000,861693034634154,1_37T02B0164MAIS,AIS140,12.976545,N,77.549759,E*50")); - - } - } diff --git a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java index 3a9382086..6b3dc3010 100644 --- a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { AtrackProtocolDecoder decoder = new AtrackProtocolDecoder(null); verifyPositions(decoder, buffer( + "@P,93D1,419,0,357766091026083,1557178589,1557178590,1557178590,-121899637,37406241,338,230,2809,8,0,0,0,0,,2000,2000,\r\n")); + + verifyPositions(decoder, buffer( "@P,3A34,146,41431,353816057242284,20180622015809,20180622015809,20180622015809,9720689,4014230,61,2,0,20,1,0,0,0,0,2000,2000,12160,42,624,002,20009,20014,\r\n")); verifyPositions(decoder, buffer( @@ -96,4 +99,23 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { } + @Test + public void testDecodeCustom() throws Exception { + + AtrackProtocolDecoder decoder = new AtrackProtocolDecoder(null); + + decoder.setCustom(true); + + decoder.setForm("%AT%BV%MV%SA%VN%PD%IA%MP%EL%ET%FC%FL%RP%ML%MF%TR%EH%DL%EG%HA%HB%HC%IP%MT"); + + verifyPositions(decoder, buffer( + "@P,7E02,186,0,357766091026083,1558908265,1558908266,1558908266,-121900220,37407524,175,2,6,6,1,39,0,0,,2000,2000, ,3,40,142,12,JN8AZ1MU1BW066090,0,30,0,58,90,22,72,1187,0,1232,9,409,0,1,0,0,0,0,1\r\n")); + + decoder.setForm("%AT%BV%CD%CE%CM%CN%DT%GN%GQ%GS%GV%LC%ME%MV%RL%SA%SM%CS%HT%VN%PD%IA%MP%EL%ET%FC%FL%RP%ML%MF%TR%EH%CR%DL%EG%HA%HB%HC%IP%MT%PF"); + + verifyPositions(decoder, buffer( + "@P,DCCE,422,5818,357766091026083,1557904779,1557904780,1557904780,-121899644,37406291,129,2,21,10,0,0,0,0,,2000,2000,,13,40,8942310017000752067,21096194,295050910083206,310260,0,FF00001F0393FF01001E0395FF01001E0394FF01001F0393FF02001D0393FF00001F0394FF0100200394FF01001F0393FF02001F0395FF0100200394,20,10,002C005C03B4,14953,357766091026083,125,38,11,0,1,Device:Fail,JN8AZ1MU1BW066090,0,0,0,0,0,99,0,0,0,0,0,264,5,0,0,0,0,0,0,0,0\r\n")); + + } + } diff --git a/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java index d3be0b6d6..71bc83b4f 100644 --- a/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class AvemaProtocolDecoderTest extends ProtocolTest { @@ -10,7 +11,14 @@ public class AvemaProtocolDecoderTest extends ProtocolTest { AvemaProtocolDecoder decoder = new AvemaProtocolDecoder(null); - verifyNull(decoder, text( + verifyAttribute(decoder, text( + "1000000000,20190527072358,121.646024,25.062135,0,0,0,0,10,0.0,1,0.02,12.32,0,0,15,2,466-5,10275,0,0.01,65EB812A000104E0,8000001234,NormanChang"), + Position.KEY_DRIVER_UNIQUE_ID, "65EB812A000104E0"); + + verifyNotNull(decoder, text( + "1000000000,20190522093835,121.645898,25.062268,0,0,0,0,3,0.0,1,0.02,11.48,0,0,19,4,466-5,65534,56589841,0.01")); + + verifyNotNull(decoder, text( "8,20180927150956,19.154864,49.124862,7,56,0,12,3,0.0,0,0.02,14.01,0,0,26,0,219-2,65534,10255884,0.01")); verifyPosition(decoder, text( diff --git a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java index 40ffbe5a5..9801b56cc 100644 --- a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java @@ -13,6 +13,12 @@ public class BceProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "3ab90b71bc1503000300c10bff11")); + verifyPositions(decoder, binary( + "cdc3440cf31403001902a58c0a06e0ceb0009f4e4452419417e0ceb08bc0ffcf428014463627b24018104b425b1c508b00d16a9743d188da6e0110ce001455069262002e4c5adabb810200418728157501004229460377000bb4d04b10c000ffff335aa800000000000000000000000000a912963d0042313130303030313236313432303031202020202020202020202020202020203f2946030301f70100007b0400009f130000762700000a26e0ceb06f074e4452419427e0ceb08bc0ffcf42801446ee28b240a40f4b425c1c518a00df414c42d188936eff0fce001455069262002e4c5adabb810200417b28157501004c294603770008b4d04b10c000ffff4c5a89000000000000000000000000009a2c8c3b004231313030303031323631343230303120202020202020202020202020202020492946030301f80100007c040000a9130000802700009477e0ceb08bc0ffcf42801446eb2fb2405c0d4b425d1c53830089e07e43d188a56eff0fce001455069262002eb35700bb810200415227167501007e294603780000b4d04b10c000ffff995700000000000000000000000000008bd9f43b004231313030303031323631343230303120202020202020202020202020202020802946030301fd01000081040000e0130000b72700000a86e0ceb064464e4452410a96e0ceb000a54e4452410aa6e0ceb000914e4452410ab6e0ceb068334e4452410ac6e0ceb0009f4e4452410ac6e0ceb06f074e445241f4")); + + verifyPositions(decoder, binary( + "cc2c5792c6160300b000a5520aa6c813ae64465343513840a7c813ae0bc0fd800080040036093f427884ea41001c900e00000000009088c562a301024156d12a004c00006df80c0000000086fb0200562a08005a000000000ac6c813ae0091534351380af6c813ae009f534351380af6c813ae6f075343513840f7c813ae0bc0fd800080040036093f427884ea41001c900e00000000009088f162a301024156d12a004c00006df80c0000000086fb0200562a08005a000000003f")); + verifyPositions(decoder, false, binary( "76145792c61603003402a59b59a7f722aa8ac00080c086000121800000280f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff000059f7f722aa8ac00080c086000121800000260f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff00000a16f822aa6f07534352325917f822aa8ac00080c086000120800000190f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff00005957f822aa8ac00080c086000121800000240f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff00000a66f822aa6f07534352325967f822aa8ac00080c086000121a00000160f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff000059b7f822aa8ac00080c086000121800000170f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff0000ef")); diff --git a/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java index bdcc1f9e8..be5877193 100644 --- a/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java @@ -9,8 +9,8 @@ public class BceProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - BceProtocolEncoder encoder = new BceProtocolEncoder(); - + BceProtocolEncoder encoder = new BceProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_OUTPUT_CONTROL); diff --git a/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java index 5ed3f5dc8..7640484d4 100644 --- a/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class CalAmpProtocolDecoderTest extends ProtocolTest { CalAmpProtocolDecoder decoder = new CalAmpProtocolDecoder(null); verifyPosition(decoder, binary( + "8308352648068863398f01070102039c5cfc4dcd5cfc4dcd19913f5dcce1291e000033fa0000005801110800019aff9d6f0e13003e0b02000000000000000000")); + + verifyPosition(decoder, binary( "83051633033459010101028afd59ae7c1459ae7c140b06bbce2c01520e0000d916000001b900450900005affa50f091f00260d040000000f24000001b90000000000003714")); verifyPosition(decoder, binary( diff --git a/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java index 27f503b34..3c35398a6 100644 --- a/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class CastelProtocolDecoderTest extends ProtocolTest { @@ -10,6 +11,13 @@ public class CastelProtocolDecoderTest extends ProtocolTest { CastelProtocolDecoder decoder = new CastelProtocolDecoder(null); + verifyAttribute(decoder, binary( + "40403a00043231334744503230313830323133343300000000a002000001000001012011004d414c43333831434d4b4d353637313438c8fc0d0a"), + Position.KEY_RESULT, "MALC381CMKM567148"); + + verifyAttributes(decoder, binary( + "404043000432313357503230313830303138323400000000004005f064d95c8365d95c9f2f0100c50200004006000000000000040003440068000000000100f3660d0a")); + verifyAttributes(decoder, binary( "40403a00043231335750323031373030363135360000000000a00200000100000101201100344a474446364545374a4230373632363056ff0d0a")); diff --git a/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java index bcb93a010..1864d9e84 100644 --- a/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java @@ -9,8 +9,8 @@ public class CastelProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - CastelProtocolEncoder encoder = new CastelProtocolEncoder(); - + CastelProtocolEncoder encoder = new CastelProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); diff --git a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java index d3066aa2d..523ad1d5c 100644 --- a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class CellocatorProtocolDecoderTest extends ProtocolTest { CellocatorProtocolDecoder decoder = new CellocatorProtocolDecoder(null); verifyPosition(decoder, binary( + "4d4347500bde66220048165400cb0000000000080600000124161400061300050402095501aaf8218787fcac390100010000070700013133150f07131905001e000100000293001e00697e6f24148240040000000083400400000000844004000000008540040000000086400400000000874004000000008840040000000089400400000000814004000000008c4004000000008d4004000000008e4004000000009140040000000090400400000000804004000000008a400400000000974004000000008b4004000000009d4004000000009b400400000000da")); + + verifyPosition(decoder, binary( "4D4347500BA9880B00880A3900EE00000000000806000001210A140002B6001E0034419B1B1900400401000000014004000000000240046000000003400480000000044004DA0A0000054004000000000640045E000000074004310000000840042B000000094004870000000B4004B10B00000C4004590000000D40040000000010400465000000114004780C000012400465650700144004A4000000154004207F000016400400000000174004000000001E4004000000001F40040000000020400400000000214004000000002440040000000006130003040211D67DA4F7883AAF028403000001000007070001250A1004090E1905001E0001000062")); verifyPosition(decoder, binary( diff --git a/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java index 89850fb5f..616640116 100644 --- a/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java @@ -11,8 +11,8 @@ public class CellocatorProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - CellocatorProtocolEncoder encoder = new CellocatorProtocolEncoder(); - + CellocatorProtocolEncoder encoder = new CellocatorProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_OUTPUT_CONTROL); diff --git a/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java index 7c03b7d5b..f0eede4bf 100644 --- a/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class CityeasyProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - CityeasyProtocolEncoder encoder = new CityeasyProtocolEncoder(); + CityeasyProtocolEncoder encoder = new CityeasyProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java index ae5e9353c..8977cf194 100644 --- a/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class DmtProtocolDecoderTest extends ProtocolTest { "0255003300001b00003335333232393032373533393235310038393931353030303030303030313330343539340000000403041910780603")); verifyPositions(decoder, false, binary( + "025504ab013d00c21a00004829900c0300154929900cbd163617b08a94c7fa003c07032c131a0302080300000000000300060f019b14037e0e0463000558140607213d00c31a0000ca29900c030015ca29900ca3033817bbb895c71401be0603b310190302080300000000000300060f019b14036d0e0463000558140607213d00c41a0000472a900c030015472a900c8d453817423e96c7fa000200040013270302080300000000000300060f019b1403840e0463000546140606213d00c51a0000c52a900c030015c52a900c184c3817c35296c724010400050016180302080300000000000300060f019b1403750e0463000547140606213d00c61a0000462b900c030015462b900cbd8a361703b495c710018c07085a10210302080300000000000300060f019b1403630e0463000546140606213d00c71a0000c52b900c030015c52b900cf6d63517455a94c7e9004c05035a10240302080300000000000300060f019b14036e0e0463000545140606213d00c81a00004b2c900c0300154b2c900c766d3517ddf093c7320107000d00102e0302080300000000000300060f019b1403750e046300054314060521")); + + verifyPositions(decoder, false, binary( "02551040000eaca40d00d2b8e562c51f9912f39a6bee00007e420091090903070100000000008b1065360000000000007fd401c4fcf2feffffffffffffffffee0000003f1b")); verifyPositions(decoder, false, binary( diff --git a/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java index e3cff9525..e24da3173 100644 --- a/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "454C0027E753035254407167747167670100180002035254407167747100200205020500010432000086BD")); + verifyAttribute(decoder, binary( + "6767070006000e0077035d"), + Position.KEY_IGNITION, true); + verifyAttributes(decoder, binary( "676707006502df5c89fde800bc3fa8030302005555045b555555057a5555550b225555550c105c55550d115555550e7e5555550f4555555510017b5555112b5555551f01ed5555208005b0012100005555407ad000004237f5555589000000498a0000aef78b00000000")); diff --git a/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java index e4502f919..616ca0b52 100644 --- a/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java @@ -13,9 +13,9 @@ public class EelinkProtocolEncoderTest extends ProtocolTest { command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); - verifyCommand(new EelinkProtocolEncoder(false), command, binary("676780000f0000010000000052454c41592c3123")); + verifyCommand(new EelinkProtocolEncoder(null, false), command, binary("676780000f0000010000000052454c41592c3123")); - verifyCommand(new EelinkProtocolEncoder(true), command, binary("454c001eb41a0123456789012345676780000f0000010000000052454c41592c3123")); + verifyCommand(new EelinkProtocolEncoder(null, true), command, binary("454c001eb41a0123456789012345676780000f0000010000000052454c41592c3123")); } diff --git a/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java index 237c849c5..523d095f2 100644 --- a/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java @@ -14,6 +14,9 @@ public class EgtsFrameDecoderTest extends ProtocolTest { binary("0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2"), decoder.decode(null, null, binary("0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2"))); + verifyFrame( + binary("0100000b000300704300db0500006c27"), + decoder.decode(null, null, binary("0100000b000300704300db0500006c270100000b0003007143009d0600003c7e"))); } } diff --git a/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java index 2210893e7..2afb72e08 100644 --- a/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java @@ -6,7 +6,30 @@ import org.traccar.ProtocolTest; public class EgtsProtocolDecoderTest extends ProtocolTest { @Test - public void testDecode() throws Exception { + public void testDecodeWithObjectId() throws Exception { + + EgtsProtocolDecoder decoder = new EgtsProtocolDecoder(null); + + verifyNull(decoder, binary( + "0100020b002300020001871c00020000010105190000ab0800006247396e615734366347467a63336476636d513daadf")); + + verifyPositions(decoder, binary( + "0100020b004600010001b81800030001f299c0d80202101500c9c52f1100552e9c80e4ca7911f5805b00000000031800040001f299c0d80202101500cbc52f1100612e9c00dbca79116c803e00000000037c13")); + + verifyPositions(decoder, binary( + "0100020b005e01030001ed180005000162c72c9a0202101500c4c52f1100477e9f0047c979010000ad000000000318000600017ee0710c0202101500c9c52f11003ee59f8061e97a0100801b00000000031800070001b6eeb6c00202101500c7c52f110077669d00b9707a116a015600000000031800080001b6eeb6c00202101500cdc52f11007c669d004e717a117a0158000000000318000900018b4685f70202101500c8c52f11006ee09f0027ca7c11650079000000000318000a0001f299c0d80202101500c9c52f1100552e9c80e4ca7911f5805b000000000318000b0001f299c0d80202101500cbc52f1100612e9c00dbca79116c803e000000000318000c0001731347010202101500c7c52f1100a3699a80db3c7a010000e5000000000318000d0001c85285f70202101500cbc52f1100e8979900f3497b114d0101000000000318000e0001aa4358810202101500cdc52f11002d689a80ab427a0100009300000000032b9f")); + + verifyNull(decoder, binary("0100000b0003006c430004010000acfb")); + + verifyPositions(decoder, binary( + "0100000b0086035ddd016d18004f049579b000001e2fc11002021015001e2fc1107ac3919f59cc5c7a0b0000000000003000180050049579b00000242fc1100202101500242fc1100fb5919f2dbf5c7a0b0000000000003000180051049579b00000312fc1100202101500312fc110b899919f94cf5c7a0b00000000000030001e0052049579b00000ba62a2120202120900000003000000000000150500025c00000013070003000000000000180053049579b000004e2fc11002021015004e2fc11087ba919f8dd45c7a0b0000000000003000180054049579b00000552fc1100202101500552fc1106ecb919f2aec5c7a0b00000000000030001e0055049579b00000d562a2120202120900000003000000000000150500025c00000013070003000000000000180056049579b000005c2fc11002021015005c2fc11059d9919f54fa5c7a0b0000000000003000180057049579b000006e2fc11002021015006e2fc110309f919fc2db5c7a0b0000000000003000180058049579b00000762fc1100202101500762fc1104690919f94cf5c7a0b00000000000030001e0059049579b00000f662a2120202120900000003000000000000150500025c000000130700030000000000001e005a049579b000001463a2120202120900000003000000000000150500025c0000001307000300000000000018005b049579b00000b32fc1100202101500b32fc110c491919fa2c65c7a0b00000000000030001e005c049579b000003363a2120202120900000003000000000000150500025c0000001307000300000000000018005d049579b00000ca2fc1100202101500ca2fc11089b9919fd5f95c7a0b00000000000030001e005e049579b000005163a2120202120900000003000000000000150500025c000000130700030000000000001e005f049579b000006f63a2120202120900000003000000000000150500025c00000013070003000000000000180060049579b00000f42fc1100202101500f42fc11087ba919f43db5c7a0b0000000000003000180061049579b000000730c11002021015000730c110f9c3919fe1c65c7a0b0000000000003000180062049579b000000930c11002021015000930c1106ecb919f3ab65c7a0b00000000000030001e0063049579b000008d63a2120202120900000003000000000000150500025c00000013070003000000000000140064049579b00000ac63a2120202120900000003000000000000150500025c000000ce53")); + + verifyNull(decoder, binary("0100000b00100091030072000100060000000002020003009203000009")); + + } + + @Test + public void testDecodeWithAuth() throws Exception { EgtsProtocolDecoder decoder = new EgtsProtocolDecoder(null); diff --git a/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java index 16f00d69b..7bf4f844e 100644 --- a/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class EsealProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - EsealProtocolEncoder encoder = new EsealProtocolEncoder(); + EsealProtocolEncoder encoder = new EsealProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java index 11492fb6f..88a460854 100644 --- a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class FifotrackProtocolDecoderTest extends ProtocolTest { @@ -10,6 +11,17 @@ public class FifotrackProtocolDecoderTest extends ProtocolTest { FifotrackProtocolDecoder decoder = new FifotrackProtocolDecoder(null); + verifyPosition(decoder, buffer( + "$$116,869270049149999,5,A01,4,190925080127,V,-15.804260,35.061506,0,0,1198,0,0,900000C0,02,0,650|10|12C|B24,18B|4C8|72,1,*01")); + + verifyAttribute(decoder, buffer( + "$$123,869467049296388,B996,A01,2,190624131813,V,22.333746,113.590670,0,124,-1,26347,0,0004,00,0,460|0|2694|5A5D,174|0|0|0,B48CEB,*77"), + Position.KEY_ALARM, Position.ALARM_SOS); + + verifyAttribute(decoder, buffer( + "$$125,869467049296388,548,A01,38,190619025856,A,22.333905,113.590261,0,12,60,16666,0,0000,00,0,460|0|2694|13F8,1A2|4C1|0|0,B4A067,*7A"), + Position.KEY_DRIVER_UNIQUE_ID, "11837543"); + verifyNull(decoder, buffer( "$$79,868345037864709,382,D05,190220085833,22.643210,114.018176,1,1,1,13152,23FFD339*25")); diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java index 53ae8510a..b60313956 100644 --- a/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java @@ -11,8 +11,8 @@ public class FifotrackProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - FifotrackProtocolEncoder encoder = new FifotrackProtocolEncoder(); - + FifotrackProtocolEncoder encoder = new FifotrackProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_REQUEST_PHOTO); diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java index 34423578d..6a68752bb 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class GalileoProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - GalileoProtocolEncoder encoder = new GalileoProtocolEncoder(); + GalileoProtocolEncoder encoder = new GalileoProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java index e2be99cb9..7e1ccb79d 100644 --- a/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java @@ -20,6 +20,9 @@ public class GatorProtocolDecoderTest extends ProtocolTest { GatorProtocolDecoder decoder = new GatorProtocolDecoder(null); verifyAttributes(decoder, binary( + "242480002600341cad190917022021812497260280594200000000c047010000135400009bb600ff00b90d")); + + verifyAttributes(decoder, binary( "2424800026364101b31608041108380273453415301532000000008000010000122800000124000000c40d")); verifyNull(decoder, binary( diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 35a96a6cf..12e64cd6d 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,13 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(null); + verifyPositions(decoder, buffer( + "+RESP:GTFRI,423031,355154083021002,Bolt4G,0,0,0,0,1,1.0,0.2,0,245.3,-85.630193,42.975280,20190729185934,310,410,500b,B0E320F,31,-1,100,20190729185934,0010$")); + + verifyAttribute(decoder, buffer( + "+RESP:GTCTN,440200,866427030007379,NOKIA3,0,0,2,,9,1,0.1,174,48.7,-1.061812,51.435270,20190717080549,0234,0015,0025,145A,,,0000,20190717081008,1D3B$"), + Position.KEY_BATTERY_LEVEL, 9); + verifyAttribute(decoder, buffer( "+RESP:GTHBM,4B0101,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$"), Position.KEY_ALARM, Position.ALARM_BRAKING); @@ -203,7 +210,7 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, buffer( "+RESP:GTFRI,210102,A10000499AEF9B,,0,1,1,9,0.5,0,288.0,-76.902364,39.578828,20161101134124,,,,,00,73,20161101134123,009D$")); - verifyAttributes(decoder, buffer( + verifyPositions(decoder, buffer( "+RESP:GTRTL,210102,A10000499AEF9B,,0,0,1,10,0.2,0,305.4,-76.902274,39.578517,20161101155001,,,,,00,73,20161101155001,00A6$")); verifyAttributes(decoder, buffer( diff --git a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java index 70c86bb23..2ad080219 100644 --- a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class GoSafeProtocolDecoderTest extends ProtocolTest { @@ -10,6 +11,18 @@ public class GoSafeProtocolDecoderTest extends ProtocolTest { GoSafeProtocolDecoder decoder = new GoSafeProtocolDecoder(null); + verifyAttribute(decoder, text( + "*GS06,356449068350122,013519070819,,SYS:G6S;V3.37;V1.1.8,GPS:A;12;N23.169866;E113.450728;0;255;54;0.79,COT:18779;,ADC:12.66;0.58,DTT:4084;E1;0;0;0;1,IWD:0;1;ad031652643fff28;23.2;1;1;86031652504fff28;24.3;2;1;e603165252a5ff28;24.2;3;1;bb0416557da6ff28;24.0#"), + Position.PREFIX_TEMP + 3, 24.0); + + verifyAttribute(decoder, text( + "*GS06,351535058659335,081234310719,,SYS:G6S;V3.37;V1.1.8,GPS:A;10;N23.169758;E113.450640;0;323;47;0.82,COT:18539;,ADC:10.81;4.07,DTT:4000;E0;0;0;0;1,IWD:0;1;9f00000655705d28;22.5#"), + Position.PREFIX_TEMP + 0, 22.5); + + verifyAttribute(decoder, text( + "*GS06,359568052580548,091946150719,1C,SYS:G3C;V1.40;V1.0.4,GPS:A;5;S25.750200;E28.204858;0;0;1337;1.68,COT:,ADC:13.12;4.06,DTT:4004;C6;0;0;10000000;0$091948150719,,SYS:G3C;V1.40;V1.0.4,GPS:A;5;S25.750200;E28.204858;0;0;1337;1.68,COT:,ADC:12.96;4.06,DTT:4004;C6;0;0;0;1#"), + Position.KEY_EVENT, 0x1C); + verifyPositions(decoder, text( "*GS06,860078024226974,101437211218,,SYS:G3SC;V3.36;V1.1.8,GPS:A;7;N3.052302;E101.787216;16;137;48;1.58,COT:4261733103,ADC:22.86;0.58;0.01,DTT:4004;E1;0;0;0;3$101439211218,,SYS:G3SC;V3.36;V1.1.8,GPS:A;8;N3.052265;E101.787200;12;152;46;1.31,COT:4261733103,ADC:22.98;0.58;0.01,DTT:4004;E1;0;0;0;3$101441211218,,SYS:G3SC;V3.36;V1.1.8,GPS:A;8;N3.052247;E101.787232;8;131;46;1.34,COT:4261733103,ADC:23.13;0.58;0.01,DTT:4004;E1;0;0;0;3$101510211218,,SYS:G3SC;V3.36;V1.1.8,GPS:A;8;N3.052150;E101.787152;0;131;40;0.97,COT:4261733160,ADC:22.88;0.58;0.01,DTT:4000;E1;0;0;0;1$101540211218,,SYS:G3SC;V3.36;V1.1.8,GPS:A;7;N3.052150;E101.787152;0;131;40;0.97,COT:4261733160,ADC:22.91;0.58;0.00,DTT:4000;E1;0;0;0;1#")); diff --git a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java index ca3ddfda8..23762f572 100644 --- a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class GotopProtocolDecoderTest extends ProtocolTest { "353327020412763,CMD-X")); verifyPosition(decoder, text( + "867688038677542,ALM-D1,V,DATE:190709,TIME:185214,LAT:50.0422838N,LON:014.4504646E,Speed:004.3,081-20,05.68")); + + verifyPosition(decoder, text( "013226009991924,CMD-T,A,DATE:130802,TIME:153721,LAT:25.9757433S,LOT:028.1087816E,Speed:000.0,X-X-X-X-81-26,000,65501-00A0-4B8E")); verifyPosition(decoder, text( diff --git a/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java index f888ee252..23a05fcee 100644 --- a/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java @@ -11,13 +11,13 @@ public class Gps103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionPeriodic() throws Exception { - Gps103ProtocolEncoder encoder = new Gps103ProtocolEncoder(); - + Gps103ProtocolEncoder encoder = new Gps103ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_POSITION_PERIODIC); command.set(Command.KEY_FREQUENCY, 300); - + assertEquals("**,imei:123456789012345,C,05m", encoder.encodeCommand(command)); } @@ -25,7 +25,7 @@ public class Gps103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustom() throws Exception { - Gps103ProtocolEncoder encoder = new Gps103ProtocolEncoder(); + Gps103ProtocolEncoder encoder = new Gps103ProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index a6008e682..d31cac534 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,21 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "78780c95130a071223200100013ad10d0a"), + Position.KEY_ALARM, Position.ALARM_GENERAL); + + verifyAttribute(decoder, binary( + "797900a87000000001020035000101003300125d7e3a180600d504b598f708814b3a001d1500340006125d7e39dc000011000a012e02620000000000000001000803537601000129800002000803102608593397620003000a89012608522933976266001800020172002b000114002c00045d7df3c70009000106000a000109002800010d002e00040000f25d002a000111002900040000017e0030000a000100b4000a00b402d0000591250d0a"), + Position.KEY_ALARM, Position.ALARM_REMOVING); + + verifyPosition(decoder, binary( + "797900a87000000001020035000100003300125d62bf3a0800e804b5994308814a87001d5d00340006115d62bf29000011000a012e02620000000000000001000803537601000129800002000803102608593397620003000a8901260852293397626600180002017d002b000116002c00045d6278ea0009000108000a00010b002800010b002e00040000f0c1002a00010000290004000000be0030000a000100b4000a00b402d00006c5490d0a")); + + verifyAttribute(decoder, binary( + "797900149b03023539303042343843454238410300139ba40d0a"), + Position.KEY_DRIVER_UNIQUE_ID, "5900B48CEB"); + verifyPosition(decoder, binary( "787821121303120b2524c70138e363085b549003d43301940057d200cd52c000006aa1ca0d0a")); @@ -289,6 +304,17 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7878058A000688290D0A")); + verifyAttribute(decoder, binary( + "78780c95130a0209321c90000112800d0a"), + Position.KEY_ALARM, Position.ALARM_ACCELERATION); + + verifyAttribute(decoder, binary( + "78780c95130a0209321c90000112800d0a"), + "alarmValue", 1); + + verifyAttribute(decoder, binary( + "78780c95130a0209321c91000112800d0a"), + Position.KEY_ALARM, Position.ALARM_BRAKING); } } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java index aceaef434..178c7b763 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java @@ -9,8 +9,8 @@ public class Gt06ProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - Gt06ProtocolEncoder encoder = new Gt06ProtocolEncoder(); - + Gt06ProtocolEncoder encoder = new Gt06ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); diff --git a/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java index c69dffce7..31e4f2dee 100644 --- a/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(null); + verifyNull(decoder, buffer( + "*HQ,135790246811220,HTBT#")); + verifyPosition(decoder, binary( "24702802061601234020031910125482600612695044000000ffffbbff000000000000000001760d04e2c9934d")); diff --git a/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java index a7ce3fc7e..155869b24 100644 --- a/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java @@ -14,7 +14,7 @@ import static org.junit.Assert.assertEquals; public class H02ProtocolEncoderTest extends ProtocolTest { - private H02ProtocolEncoder encoder = new H02ProtocolEncoder(); + private H02ProtocolEncoder encoder = new H02ProtocolEncoder(null); private Date time = Date.from( LocalDateTime.of(LocalDate.now(), LocalTime.of(1, 2, 3)).atZone(ZoneOffset.systemDefault()).toInstant()); diff --git a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java index 319d34e4c..6033bc744 100644 --- a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class HuaShengProtocolDecoderTest extends ProtocolTest { "c000000077aa0200000000000e000100143347315f48312e315f56312e30372e54000300133335353835353035303434303635380004000b3531323030303000050005010006000400070004000800050000090018383936313032353431343533333239313833360d000a000f796573696e7465726e6574c0")); verifyPosition(decoder, binary( + "c000000060aa000000000000fa8000000031393037303431363434323700e9900affd61c1b00000000003a000000010015ffffff0000000000000004c2ffffffffff0005000a0d080000ca6a000900155741555a5a5a344730454e313133373233c0")); + + verifyPosition(decoder, binary( "c00000004baa0000000000000f8000000031363130323030373236333600e6d4f9ffcc78c700000022003600000001001500000000000000000000059bffffffffff0005000a040300000253c0")); verifyPosition(decoder, binary( diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java index 771e6d28c..d0a0427c8 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java @@ -11,8 +11,8 @@ public class HuabaoProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - HuabaoProtocolEncoder encoder = new HuabaoProtocolEncoder(); - + HuabaoProtocolEncoder encoder = new HuabaoProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); diff --git a/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java index 1992892df..4126c4e4f 100644 --- a/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java @@ -12,6 +12,12 @@ public class ItsProtocolDecoderTest extends ProtocolTest { ItsProtocolDecoder decoder = new ItsProtocolDecoder(null); verifyPosition(decoder, text( + "$,ID01,SAT,1.0.0,NR,1,L,868345034056903,DL3CAB1021,1,27052019,040234,28.359895,N,76.927879,E,0.0,285.6,12,254.9,1.4,0.7,IDEA,1,1,12.6,3.8,0,25,404,04,0138,0927,4ECD,0138,41,1C2B,0138,37,D77A,0138,34,D843,0138,33,0000,00,0.03,0.00,000091,A3,*")); + + verifyPosition(decoder, text( + "$NMP,GPSBOX,1.6.8,NR,H,868997035844834,0000,1,220519,035419,28.6291409,N,77.3928299,E,015.2,157.40,07,197.86,2.1,1.0,airtel,1,1,13.3,4.1,0,O,31,404,10,0099,79b4,(-57,0099,334c,x,x,x,x,x,x,x,x,x),0012,00,000348,2,08.4,00.3,(0,0,0),CD*")); + + verifyPosition(decoder, text( "$RLP,N.A,2.0.2,NR,01,L,869867030181814,N.A,28022019,180155,1,28.688226,N,076.993570,E,0.0,80.26,17,201.0,0.89,0.60,VODAFONE I,0,1,25.0,4.20,0,C,14,404,11,415,F34A,51f7,415,13,840b,415,8,a3f7,0c2,5,ef77,415,5,0001,00,17888,47,*")); verifyAttribute(decoder, text( @@ -67,6 +73,24 @@ public class ItsProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "$,04,XYZ123,0.0.1,BR,06,L,861359034137271,MH12AB1234,0,00,00,0000,00,00,00,000.000000,N,000.000000,E,000.0,000.00,00,000.0,00.00,00.00,IDEAIN,1,1,00.0,3.8,1,O,17,404,22,2797,11b7,11b9,2797,-093,11b8,2797,-098,0000,0000,0000,0000,0000,0000,1000,00,000006,abd26284,")); + verifyNull(decoder, text( + "$Header,nliven,EMR,861693034634154,NM,09112017155133,A,12.976495,N,77.549713,E,906.0,0.0,23,G,KA01I2000,+919844098440*4B")); + + verifyNull(decoder, text( + "$EPB,iTriangle1,EMR,864495034445822,SP,03082018110730,A,22.829292,N,75.935806,E,543.0,0.0,0,G,KA01G1234,+9164061023*13")); + + verifyPosition(decoder, text( + "$Header,iTriangle,1_37T02B0164MAIS_2,NR,1,L,864495034490141,KA01I2000,1,19042018,102926,22.846401,N,75.948952,E,0.0,311,5,578.0,3.80,3.67,AirTel,0,1,12.5,4.3,1,C,14,404,93,0456,16db,29,ebd8,0458,28,3843,18ab,25,072e,18ab,22,35da,0458,0000,00,031181,0.0,0.0,0,()*34")); + + verifyPosition(decoder, text( + "$Header,nliven,1_37T02B0164MAIS,BR,6,L,861693034634154,KA01I2000,1,09112017,160702,12.976593,N,77.549782,E,25.1,344,15,911.0,1.04,0.68,Airtel,1,1,11.8,3.8,1,C,24,404,45,61b4,9ad9,31,9adb,61b4,35,ffff,0000,33,ffff,0000,31,ffff,0000,0001,00,000014,0.0,0.1,4,()*1E")); + + verifyPosition(decoder, text( + "$Header,iTriangle,1_37T02B0164MAIS_2,NR,1,L,864495034490141,KA01I2000,1,31032018,122247,22.845999,N,75.949005,E,0.0,44,16,545.0,1.19,0.65,AirTel,1,1,12.0,4.3,0,C,13,404,93,0456,16db,27,16dd,0456,22,3843,18ab,19,ebd8,0458,14,072c,18ab,0101,00,003735,0.0,0.0,0,()*48")); + + verifyNull(decoder, text( + "$Header,nliven,KA01I2000,861693034634154,1_37T02B0164MAIS,AIS140,12.976545,N,77.549759,E*50")); + } } diff --git a/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java index e7c4318b3..225edd643 100644 --- a/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class ItsProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - ItsProtocolEncoder encoder = new ItsProtocolEncoder(); + ItsProtocolEncoder encoder = new ItsProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java index ae0948987..e695624a9 100644 --- a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java @@ -11,6 +11,10 @@ public class Jt600FrameDecoderTest extends ProtocolTest { Jt600FrameDecoder decoder = new Jt600FrameDecoder(); verifyFrame( + binary("2478905197081711003405101917164812492365028134847d0a1c000002640c0000000020c032759600731000000f0f0f0f0f0f0f0f0f0f000702850274"), + decoder.decode(null, null, binary("2478905197081711003405101917164812492365028134847d0a1c000002640c0000000020c032759600731000000f0f0f0f0f0f0f0f0f0f000702850274"))); + + verifyFrame( binary("24315011626912001b21111718095900000000000000000e0000005c000000000000000000"), decoder.decode(null, null, binary("24315011626912001b21111718095900000000000000000e0000005c00000000000000000024315011626912001b22111708130400000000000000000e0000005a00000000000000000024315011626912001b22111708140400000000000000000e0000005a000000723e18a61b01"))); diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 1ffa2a429..4a3c752cd 100644 --- a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -12,6 +12,15 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { Jt600ProtocolDecoder decoder = new Jt600ProtocolDecoder(null); verifyPositions(decoder, binary( + "2478807035371711003419081920061851380856003256223b000000000000070000000020c0ff965d54de1800000f0f0f0f0f0f0f0f0f0f02d600ea0a21")); + + verifyPositions(decoder, binary( + "2475201509261611002313101503464722331560113555309F00000000002D0500CB206800F064109326381A03")); + + verifyPositions(decoder, binary( + "2475810297431713003401010000030100000000000000000e000000000001000000000020e0641aba1b6f1b00000f0f0f0f0f0f0f0f0f0f000001942803")); + + verifyPositions(decoder, binary( "2440811188882400A209060908045322564025113242329F0598000001003F0000002D0009060908050322564025113242329F0598000001003F0000002D0009060908051322564025113242329F0598000001003F0000002D0009060908052322564025113242329F0598000001003F0000002D0009060908053322564025113242329F0598000001003F0000002D0009060908054322564025113242329F0598000001003F0000002D001F")); verifyPositions(decoder, binary( diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java index 100d7492a..c0b399c63 100644 --- a/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java @@ -7,7 +7,7 @@ import org.traccar.ProtocolTest; import org.traccar.model.Command; public class Jt600ProtocolEncoderTest extends ProtocolTest { - Jt600ProtocolEncoder encoder = new Jt600ProtocolEncoder(); + Jt600ProtocolEncoder encoder = new Jt600ProtocolEncoder(null); Command command = new Command(); @Test diff --git a/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java index ab858041a..390defe6f 100644 --- a/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java @@ -9,8 +9,8 @@ public class KhdProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - KhdProtocolEncoder encoder = new KhdProtocolEncoder(); - + KhdProtocolEncoder encoder = new KhdProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); diff --git a/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java index 31a0434bc..5b66ed865 100644 --- a/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java @@ -15,14 +15,14 @@ public class LaipacProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "$AVSYS,99999999,V1.50,SN0000103,32768*15")); - + verifyNull(decoder, text( "$ECHK,99999999,0*35")); - + verifyNull(decoder, text( "$AVSYS,MSG00002,14406,7046811160,64*1A")); - verifyNull(decoder, text( + verifyAttributes(decoder, text( "$EAVSYS,MSG00002,8931086013104404999,,Owner,0x52014406*76")); verifyNull(decoder, text( @@ -85,10 +85,10 @@ public class LaipacProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "$AVRMC,MSG00002,125517,R,5053.0442,N,00557.8694,E,0.00,0.00,240614,H,4076,167,1,0,0,0D7AB913,020408*75")); - + verifyPosition(decoder, text( "$AVRMC,MSG00002,043104,p,5114.4664,N,00534.3308,E,0.00,0.00,280614,0,4115,495,1,0,0,0D48C3DC,020408*52")); - + verifyPosition(decoder, text( "$AVRMC,MSG00002,050601,P,5114.4751,N,00534.3175,E,0.00,0.00,280614,0,4115,495,1,0,0,0D48C3DC,020408*7D")); @@ -104,22 +104,29 @@ public class LaipacProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "$AVRMC,999999999999999,084514,r,5050.1314,N,00419.9719,E,0.68,306.39,120318,0,3882,84,1,0,0,3EE4A617,020610*4D")); - //Alarm button + // Alarm button verifyPosition(decoder, text( "$AVRMC,358174067149865,142945,R,5050.1254,N,00420.0490,E,0.00,0.00,190318,3,3455,119,1,0,0,3EE4A617,020610*53")); - //G-Sensor + // G-Sensor verifyPosition(decoder, text( "$AVRMC,358174067149865,143407,R,5050.1254,N,00420.0490,E,0.00,0.00,190318,8,3455,119,1,0,0,3EE4A617,020610*52")); - //Powered off + // Powered off verifyPosition(decoder, text( "$AVRMC,358174067149865,143648,A,5050.1141,N,00420.0525,E,1.24,174.38,190318,H,3455,119,1,0,0,3EE4A617,020610*3E")); - //No network + // No network verifyPosition(decoder, text( "$AVRMC,358174067149865,143747,R,5050.1124,N,00420.0542,E,1.34,161.96,190318,a,3416,119,1,0,0*7D")); + // Zero LAC, CID, MCC, MNC + verifyPosition(decoder, text( + "$AVRMC,358174067149865,143747,P,5050.1124,N,00420.0542,E,1.34,161.96,190318,A,3416,119,1,0,0,0,0*5F")); + + // New unknown parameters + verifyPosition(decoder, text( + "$AVRMC,358174067149865,143747,P,5050.1124,N,00420.0542,E,1.34,161.96,190318,A,3416,119,1,0,0,0,0,0,0*5F")); } } diff --git a/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java new file mode 100644 index 000000000..7fe405ea8 --- /dev/null +++ b/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class LeafSpyProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + LeafSpyProtocolDecoder decoder = new LeafSpyProtocolDecoder(null); + + verifyNull(decoder, request( + "/?Lat=60.0&Long=30.0")); + + verifyPosition(decoder, request( + "/?user=driver&pass=123456&DevBat=80&Gids=200&Lat=60.0&Long=30.0&Elv=5&Seq=50&Trip=1&Odo=10000&SOC=99.99&AHr=55.00&BatTemp=15.2&Amb=12.0&Wpr=12&PlugState=0&ChrgMode=0&ChrgPwr=0&VIN=ZE0-000000&PwrSw=1&Tunits=C&RPM=1000")); + + } + +} diff --git a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java index ee4a869f9..d7aa25be8 100644 --- a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class MeiligaoProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - MeiligaoProtocolEncoder encoder = new MeiligaoProtocolEncoder(); + MeiligaoProtocolEncoder encoder = new MeiligaoProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java index b63ce5051..2b5054cee 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java @@ -11,8 +11,8 @@ public class MeitrackProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - MeitrackProtocolEncoder encoder = new MeitrackProtocolEncoder(); - + MeitrackProtocolEncoder encoder = new MeitrackProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_POSITION_SINGLE); diff --git a/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java new file mode 100644 index 000000000..794b2b57e --- /dev/null +++ b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java @@ -0,0 +1,37 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class MictrackProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + MictrackProtocolDecoder decoder = new MictrackProtocolDecoder(null); + + verifyPosition(decoder, text( + "MT;6;866425031361423;R0;10+190109091803+22.63827+114.02922+2.14+69+2+3744+113"), + position("2019-01-09 09:18:03.000", true, 22.63827, 114.02922)); + + verifyAttributes(decoder, text( + "MT;6;866425031377981;R1;190108024848+6a:db:54:5a:79:6d,-91,00:9a:cd:a2:e6:21,-94+3+3831+0")); + + verifyAttributes(decoder, text( + "MT;1;866425031379169;R2;181129081017+0,21681,20616,460+4+3976+0")); + + verifyAttributes(decoder, text( + "MT;1;866425031379169;R3;181129081017+0,167910723,14924,460,176+4+3976+0")); + + verifyAttributes(decoder, text( + "MT;6;866425031377981;R12;190108024848+6a:db:54:5a:79:6d,-91,00:9a:cd:a2:e6:21,-94+0,21681,20616,460+3+3831+0")); + + verifyAttributes(decoder, text( + "MT;6;866425031377981;R13;190108024848+6a:db:54:5a:79:6d,-91,00:9a:cd:a2:e6:21,-94+0,167910723,14924,460,176+3+3831+0")); + + verifyAttributes(decoder, text( + "MT;5;866425031379169;RH;5+190116112648+0+0+0+0+11+3954+1")); + + } + +} diff --git a/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java index e9422da9f..5de1346a2 100644 --- a/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class MiniFinderProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - MiniFinderProtocolEncoder encoder = new MiniFinderProtocolEncoder(); + MiniFinderProtocolEncoder encoder = new MiniFinderProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index 2b1fdf988..c0ce67cb6 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { Minifinder2ProtocolDecoder decoder = new Minifinder2ProtocolDecoder(null); + verifyNull(decoder, binary( + "ab10150076f1320003100133353534363530373130323933303602105a")); + + verifyPosition(decoder, binary( + "ab103f007e2533000110013335353436353037313032393330360930e09d245d210100000924b49e245d01025b201620e6c03b1ef367420400000000aa026d00c90e0000100110")); + verifyAttributes(decoder, binary( "ab1845005d39370301100133353836383830303030303338303209245b92b55c84004b610502001000002221ca00050b4a005cc30f4a0056c80f4a003ba90e4a0055c8074a005dc3034a0057c8")); diff --git a/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java new file mode 100644 index 000000000..450f77144 --- /dev/null +++ b/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java @@ -0,0 +1,19 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class NavisetFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + NavisetFrameDecoder decoder = new NavisetFrameDecoder(); + + verifyFrame( + binary("1310e4073836383230343030353935383436362a060716"), + decoder.decode(null, null, binary("1310e4073836383230343030353935383436362a060716"))); + + } + +} diff --git a/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java new file mode 100644 index 000000000..09ea10f1f --- /dev/null +++ b/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java @@ -0,0 +1,30 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class NavisetProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + NavisetProtocolDecoder decoder = new NavisetProtocolDecoder(null); + + verifyNull(decoder, binary( + "1310e4073836383230343030353935383436362a060716")); + + verifyPositions(decoder, binary( + "6b511a203f95162b7822515d78a92503042df6030000ff040000c4003f1922471000001af3000030e4503490e8ff00000000000000000000000000000000ff27000000000000808080808080808000000000ffdd0000000000000000000000000000000000000000000000210000000000ff00000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096160b7d22515d3ca92503e42cf6030000ff040000c7001ef521471000001af3000070e44034e0e8ff00000000000000000000000000000000ff27000000000000808080808080808000000000ffdd0000000000000000000000000000000000000000000000210000000000ff00000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664a")); + + verifyPositions(decoder, binary( + "b7501a203fab0d0bffcf4b5df0a82503a02cf6030000ff0c4200ba0007462a3a10000098280000f0f610fc4042ff00000000000000000000000000000000ff26000000000000808080808080808000000000ff000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008bff")); + + verifyPositions(decoder, binary( + "b7501a203fda0d097fdc4b5d70aa2503c42cf6030000ff0fb40dea0006b12a3a100000b228000080f210044041ff00000000000000000000000000000000ff25000000000000808080808080808000000000ff1201000000000000000000000000000000000000000000001a0000000000ff00000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b603")); + + verifyPositions(decoder, binary( + "14501a2000a50c0955a64b5db8a92503fc2cf603000084ab")); + + } + +} diff --git a/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java index 38599e0ba..4991f1371 100644 --- a/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java @@ -9,8 +9,8 @@ public class NoranProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - NoranProtocolEncoder encoder = new NoranProtocolEncoder(); - + NoranProtocolEncoder encoder = new NoranProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); diff --git a/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java new file mode 100644 index 000000000..ade2804da --- /dev/null +++ b/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java @@ -0,0 +1,32 @@ +package org.traccar.protocol; + +import io.netty.buffer.Unpooled; +import org.junit.Test; +import org.traccar.ProtocolTest; + +import static org.junit.Assert.assertEquals; + +public class PacificTrackProtocolDecoderTest extends ProtocolTest { + + @Test + public void testReadBitExt() { + + assertEquals(0x35, PacificTrackProtocolDecoder.readBitExt( + Unpooled.wrappedBuffer(new byte[] { (byte) 0b10110101 }))); + + assertEquals(0x135, PacificTrackProtocolDecoder.readBitExt( + Unpooled.wrappedBuffer(new byte[] { (byte) 0b00000010, (byte) 0b10110101 }))); + } + + + @Test + public void testDecode() throws Exception { + + PacificTrackProtocolDecoder decoder = new PacificTrackProtocolDecoder(null); + + verifyPosition(decoder, binary( + "fb82e80280883527530900009110818202c0909308990b122519076138fc03b3480205a3e80003a0834dd19fb08112c08f0143000e020000000100000014000101929f806328c0000f4240810a858ce011314334424a57464758444c3533313737330190868102100828cf")); + + } + +} diff --git a/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java new file mode 100644 index 000000000..582ed9a5a --- /dev/null +++ b/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java @@ -0,0 +1,27 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class PluginProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + PluginProtocolDecoder decoder = new PluginProtocolDecoder(null); + + verifyPosition(decoder, text( + "$$STATUS,fleet40,20190704122622,26.259431,-29.027889,0,9,0,-1,2,19719,805315969,0,0,0")); + + verifyPosition(decoder, text( + "$$ALARM801739,20190612121950,28.254067,-25.860494,0,0,0,-1,2,2,12595331,0,0,0,+,22,0,0,0,0,0,,0,0")); + + verifyPosition(decoder, text( + "$$STATUS801739,20190528143943,28.254086,-25.860665,0,0,0,-1,2,78,11395,0,0,0")); + + verifyPosition(decoder, text( + "50000,20150623184513,113.828759,22.709578,70,190,0,-1,2,155135681,805327235,1.32,-32.1,0")); + + } + +} diff --git a/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java index 1b2780325..aa08ecea2 100644 --- a/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java @@ -11,13 +11,13 @@ public class PretraceProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionPeriodic() throws Exception { - PretraceProtocolEncoder encoder = new PretraceProtocolEncoder(); - + PretraceProtocolEncoder encoder = new PretraceProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_POSITION_PERIODIC); command.set(Command.KEY_FREQUENCY, 300); - + assertEquals("(123456789012345D221300,300,,^69)", encoder.encodeCommand(command)); } @@ -25,7 +25,7 @@ public class PretraceProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustom() throws Exception { - PretraceProtocolEncoder encoder = new PretraceProtocolEncoder(); + PretraceProtocolEncoder encoder = new PretraceProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Pt215FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Pt215FrameDecoderTest.java new file mode 100644 index 000000000..2e3600b99 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Pt215FrameDecoderTest.java @@ -0,0 +1,27 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Pt215FrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Pt215FrameDecoder decoder = new Pt215FrameDecoder(); + + verifyFrame( + binary("58580d010359339075799656010d0a"), + decoder.decode(null, null, binary("58580d010359339075799656010d0a"))); + + verifyFrame( + binary("5858071340010819640d0a"), + decoder.decode(null, null, binary("5858071340010819640d0a"))); + + verifyFrame( + binary("585815101309160d0f0c9902b7015405f0e82404347afff7000d0a"), + decoder.decode(null, null, binary("585815101309160d0f0c9902b7015405f0e82404347afff7000d0a"))); + + } + +} diff --git a/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java new file mode 100644 index 000000000..59574aeee --- /dev/null +++ b/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Pt215ProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Pt215ProtocolDecoder decoder = new Pt215ProtocolDecoder(null); + + verifyNull(decoder, binary( + "58580d010359339075435451010d0a")); + + verifyNull(decoder, binary( + "585801080d0a")); + + } + +} diff --git a/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java index a6c8bb50f..9e4a8a9a0 100644 --- a/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustom() throws Exception { - Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(); + Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); @@ -25,22 +25,22 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeOutputControl() throws Exception { - Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(); - + Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_OUTPUT_CONTROL); command.set(Command.KEY_INDEX, 2); command.set(Command.KEY_DATA, "1"); - + assertEquals("#OPC2,1\r\n", encoder.encodeCommand(command)); } - + @Test public void testEncodeTimezone() throws Exception { - Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(); + Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); @@ -55,7 +55,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeAlarmSpeed() throws Exception { - Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(); + Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java new file mode 100644 index 000000000..318cbdb51 --- /dev/null +++ b/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class RaceDynamicsProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + RaceDynamicsProtocolDecoder decoder = new RaceDynamicsProtocolDecoder(null); + + verifyNull(decoder, text( + "$GPRMC,12,260819,100708,862549040661129,")); + + verifyPositions(decoder, text( + "$GPRMC,15,04,H,#,100632,A,1255.5106,N,07738.2954,E,001,260819,0887,06,1,00011,%,0000000000000000,000,000,0,0,1,0713,0,416,0,255,000,0,000,3258,000,000,00,0000,000,00000,0,F3VF01,%,#,#,100633,A,1255.5107,N,07738.2955,E,001,260819,0887,06,1,00012,%,0000000000000000,000,000,0,0,1,0713,0,416,0,255,000,0,000,3453,000,000,00,0000,000,00000,0,F3VF01,%,#,#,100634,A,1255.5106,N,07738.2964,E,001,260819,0887,06,1,00013,%,0000000000000000,000,000,0,0,1,0713,0,392,0,255,000,0,000,3651,000,000,00,0000,000")); + + } + +} diff --git a/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java new file mode 100644 index 000000000..66286776a --- /dev/null +++ b/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java @@ -0,0 +1,26 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Position; + +public class RstProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + RstProtocolDecoder decoder = new RstProtocolDecoder(null); + + verifyAttribute(decoder, text( + "RST;A;RST-MINIv2;V7.00;008033985;1;7;30-08-2019 11:31:38;30-08-2019 11:31:15;-23.645868;-46.637741;0;226;828;0;10;0;00;20;00;1A;02;0.02;3.40;0;0;FE;0000;04;80;11;0;FIM;"), + Position.KEY_BATTERY, 3.40); + + verifyPosition(decoder, text( + "RST;A;RST-MINIv2;V7.00;008033985;1;7;30-08-2019 11:31:38;30-08-2019 11:31:15;-23.645868;-46.637741;0;226;828;0;10;0;00;20;00;1A;02;0.02;3.40;0;0;FE;0000;04;80;11;0;FIM;")); + + verifyPosition(decoder, text( + "RST;A;RST-MINIv2;V7.00;008033985;6;47;30-08-2019 19:01:13;30-08-2019 19:01:14;-23.645851;-46.637817;0;294;811;1;11;0;00;30;00;1A;02;3.82;4.16;0;0;FE;0000;02;40;71;000001F60A55;FIM;")); + + } + +} diff --git a/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java index 8a00caa09..5868b07df 100644 --- a/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java @@ -9,8 +9,8 @@ public class RuptelaProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - RuptelaProtocolEncoder encoder = new RuptelaProtocolEncoder(); - + RuptelaProtocolEncoder encoder = new RuptelaProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_CUSTOM); diff --git a/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java index 48adb0ccb..a2cb021ef 100644 --- a/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java @@ -3,6 +3,7 @@ package org.traccar.protocol; import io.netty.handler.codec.http.HttpMethod; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class SigfoxProtocolDecoderTest extends ProtocolTest { @@ -12,6 +13,19 @@ public class SigfoxProtocolDecoderTest extends ProtocolTest { SigfoxProtocolDecoder decoder = new SigfoxProtocolDecoder(null); verifyPosition(decoder, request(HttpMethod.POST, "/", + buffer("{ \"device\": \"49F941\", \"location\": {\"lat\":19.48954345634299,\"lng\":-99.09340606338463,\"radius\":1983,\"source\":2,\"status\":1} }"))); + + verifyAttribute(decoder, request(HttpMethod.POST, "/", + buffer("{ \"device\": \"40D310\", \"payload\": \"62\", \"time\": 1563043532, \"seqNumber\": 1076 }")), + Position.KEY_ALARM, Position.ALARM_SOS); + + verifyAttributes(decoder, request(HttpMethod.POST, "/", + buffer("{ \"device\": \"40D310\", \"payload\": \"20061494480389f956042a\", \"time\": 1563043532, \"seqNumber\": 1076 }"))); + + verifyPosition(decoder, request(HttpMethod.POST, "/", + buffer("{ \"device\": \"1CEDCE\", \"payload\": \"2002419b4a91c2c6580e0564\", \"time\": 1559924939, \"seqNumber\": 87 }"))); + + verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("%7B++%22device%22%3A%222BF839%22%2C++%22time%22%3A1510605882%2C++%22duplicate%22%3Afalse%2C++%22snr%22%3A45.61%2C++%22station%22%3A%2235A9%22%2C++%22data%22%3A%2200bd6475e907398e562d01b9%22%2C++%22avgSnr%22%3A45.16%2C++%22lat%22%3A-38.0%2C++%22lng%22%3A145.0%2C++%22rssi%22%3A-98.00%2C++%22seqNumber%22%3A228+%7D="))); } diff --git a/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java index 70e173284..97246a665 100644 --- a/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java @@ -49,6 +49,11 @@ public class StarLinkProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "$SLU006968,06,375154,170117052613,04,170117052612,+3203.2079,+03448.1369,000.0,300,085725,1,1,0,0,0,0,0,0,10422,36201,14.287,04.084,,1,0*5B")); + decoder.setFormat("#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#,#LAC#,#CID#,#VIN#,#VBAT#"); + + verifyPosition(decoder, text( + "$SLU352353083185436,06,85,190527214903,01,190527214903,+0614.1883,-07535.5033,000.0,000,000082.505,5070,50473,0,12.148,03.507,,100,0.02,35.0,1,1513,60,1,99*30")); + } } diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index cb5df63e6..304bc0fed 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -59,6 +59,13 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(null); verifyPosition(decoder, text( + "ALT;0520000295;3FFFFF;52;1.0.2;0;20190703;01:03:24;00004697;732;101;0002;59;+4.682583;-74.128142;0.00;0.00;6;1;00000000;00000000;9;1;;4.1;12.92;103188")); + + verifyAttribute(decoder, text( + "ST300UEX;109003241;08;1026;20190425;17:36:04;04402;+04.722553;-074.052583;000.020;000.00;10;1;0;12.04;010000;51;CabAVL\"CabMensaje,0,58.5,-1.0,,,FinMensaje\"FinAVL\r\n;B1;0000000000;4.1;1"), + "fuel1", 58.5); + + verifyPosition(decoder, text( "ST600UEX;008728327;20;520;20190218;10:56:51;0bf1a893;334;20;2f19;18;+20.514195;-100.743597;000.015;000.00;9;1;3720808;12.89;000000;44;t_0=0D;N_0=0551.0;t_1=14;N_1=039F.0;Q_D=0B\r\n;9E;010440;4.1;1")); verifyPosition(decoder, text( diff --git a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java index f21acdee7..c0511f2a1 100644 --- a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class T55ProtocolDecoderTest extends ProtocolTest { @@ -13,6 +14,10 @@ public class T55ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "$DEVID,0x0103846677F21422*41")); + verifyAttribute(decoder, text( + "$GPIOP,01000000,00000000,0.00,0.00,0.00,0.00,4.69,4.24*49"), + Position.KEY_BATTERY, 4.24); + verifyPosition(decoder, text( "660420156A0066AA$GPRMC,122806.0,A,0119.212178,N,10355.000942,E,0.0,,230119,0.0,E,A*27")); diff --git a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java index bfe06b5cd..28b3fc5c6 100644 --- a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java @@ -11,6 +11,19 @@ public class T800xProtocolDecoderTest extends ProtocolTest { T800xProtocolDecoder decoder = new T800xProtocolDecoder(null); + verifyPosition(decoder, binary( + "2727040049001b0866425039645728c916190604005240000000007739d2c25b681f420000000080000081000020174105000005458216001e000000f01e00001e30d0000000000000")); + + verifyAttribute(decoder, binary( + "272705005e000108664250328807851905301107481054002d004d006f00620069006c006500074341542d4e42310a4c54452042414e4420340f333130323430323030303032333030143839303132343032303531303030323330303746"), + Position.KEY_OPERATOR, "T-Mobile"); + + verifyPosition(decoder, binary( + "272702004904a90866425032880785c800190530080350000000000705eec29bf50842000000000008008090502a003700000a9e358002003c000003841900001e3f90000000000000272702004904aa0866425032880785c800190530081851000000000705eec29bf50842000000000008008090602e003700000a9e358002003c000003841900001e3f90000000000000")); + + verifyNull(decoder, binary( + "2727010017000108806168988888881016010207110111")); + verifyNull(decoder, binary( "252501001504050880061689888888111111250350")); diff --git a/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java index e41b91281..9a628cdb6 100644 --- a/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java @@ -9,14 +9,16 @@ public class T800xProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - T800xProtocolEncoder encoder = new T800xProtocolEncoder(); - + T800xProtocolEncoder encoder = new T800xProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_CUSTOM); command.set(Command.KEY_DATA, "RELAY,0000,On#"); - verifyCommand(encoder, command, binary("252581001e000101234567890123450152454c41592c303030302c4f6e23")); + verifyFrame( + binary("232381001e000101234567890123450152454c41592c303030302c4f6e23"), + encoder.encodeCommand(null, command)); } diff --git a/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java index bdbaec8aa..0b9eacb8d 100644 --- a/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TaipProtocolDecoderTest extends ProtocolTest { TaipProtocolDecoder decoder = new TaipProtocolDecoder(null); + verifyNull(decoder, text( + ">RLN25601000+297185103-0955755990+000059150000+0000000012000000000000000000000000000000000000000000000000000000000012;ID=3580;*48<")); + verifyPosition(decoder, text( ">RGP211217112154-2748332-058946350000000FF7F2100;ID=AA01;#0002;*2D<")); diff --git a/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java index 0fdd26a47..767f175fe 100644 --- a/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java @@ -11,11 +11,11 @@ public class TechTltProtocolDecoderTest extends ProtocolTest { TechTltProtocolDecoder decoder = new TechTltProtocolDecoder(null); verifyPosition(decoder, text( - "002422269*POS=Y,16:21:20,25/11/09,3809.8063N,01444.7438E,4.17,117.23,0.4,09,40076,56341"), + "002422269*POS=Y,16:21:20,25/11/09,3809.8063N,01444.7438E,4.17,117.23,0.4,09,40076,56341\r\n"), position("2009-11-25 16:21:20.000", true, 38.16344, 14.74573)); - verifyNull(decoder, text( - "002422269,INFOGPRS,V Bat=13.8,TEMP=23,I TIM,15")); + verifyAttributes(decoder, text( + "002422269,INFOGPRS,V Bat=13.8,TEMP=23,I TIM,15\r\n")); } diff --git a/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java new file mode 100644 index 000000000..8d2e70bd4 --- /dev/null +++ b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java @@ -0,0 +1,23 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class TeltonikaFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + TeltonikaFrameDecoder decoder = new TeltonikaFrameDecoder(); + + verifyFrame( + binary("000F313233343536373839303132333435"), + decoder.decode(null, null, binary("FF000F313233343536373839303132333435"))); + + verifyFrame( + binary("000F313233343536373839303132333435"), + decoder.decode(null, null, binary("000F313233343536373839303132333435"))); + + } + +} diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index b515fbdc6..827e12a96 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -16,6 +16,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { "000F313233343536373839303132333435")); verifyPositions(decoder, false, binary( + "000000000000004f0c01060000004755555555777730362e343b30342e323b30302e303b30302e303b30302e303b30302e303b30302e303b30302e303b30312e333b30302e303b31302e373b30302e303b5353530d0a010000e371")); + + verifyPositions(decoder, false, binary( "00000000000000100C010600000008010300010015D5C5010000D988")); verifyPositions(decoder, binary( diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java index 5dc78c012..0318b9896 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java @@ -9,8 +9,8 @@ public class TeltonikaProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - TeltonikaProtocolEncoder encoder = new TeltonikaProtocolEncoder(); - + TeltonikaProtocolEncoder encoder = new TeltonikaProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_CUSTOM); diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java index 34b2acf86..d1dad8c92 100644 --- a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeOutputControl() { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); @@ -25,8 +25,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeEngineStop() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(); - + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); @@ -38,8 +38,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionSingle() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(); - + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_POSITION_SINGLE); @@ -51,8 +51,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionPeriodic() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(); - + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_POSITION_PERIODIC); @@ -65,8 +65,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionStop() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(); - + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_POSITION_STOP); @@ -78,8 +78,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeGetVersion() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(); - + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_GET_VERSION); @@ -91,8 +91,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeRebootDevice() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(); - + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_REBOOT_DEVICE); @@ -104,8 +104,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeSetOdometer() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(); - + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_ODOMETER); @@ -117,7 +117,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionSingleAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); @@ -130,7 +130,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionPeriodicAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); @@ -143,7 +143,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionStopAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); @@ -156,7 +156,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeGetVersionAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); @@ -169,7 +169,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeRebootDeviceAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); @@ -182,7 +182,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeIdentificationAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); @@ -195,7 +195,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeSosOnAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); @@ -209,7 +209,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeSosOffAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); @@ -223,7 +223,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustom() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); @@ -237,7 +237,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustomAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); @@ -251,7 +251,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeSetConnectionAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); @@ -266,7 +266,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeSosNumberAlternative() throws Exception { - Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true); + Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java index 5a47f74cc..d8c54afbe 100644 --- a/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java @@ -11,13 +11,13 @@ public class TotemProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - TotemProtocolEncoder encoder = new TotemProtocolEncoder(); - + TotemProtocolEncoder encoder = new TotemProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(2); command.setType(Command.TYPE_ENGINE_STOP); command.set(Command.KEY_DEVICE_PASSWORD, "000000"); - + assertEquals("*000000,025,C,1#", encoder.encodeCommand(command)); } diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java index 2fdb86218..aceb9e122 100644 --- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class TrvProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "TRVAP00352121088015548")); + verifyPosition(decoder, text( + "TRVYP03190805A1828.9242N07353.9423E000.0150716029.0010000810020201112,404,27,184,10229")); + verifyNotNull(decoder, text( "IWAP02,zh_cn,0,6,260,1,11002|39252|9,11002|35112|23,11002|11043|24,11002|39253|24,11002|13751|24,11018|8102|26,3,a|c0-4a-00-b6-9c-f5|64&a|c0-4a-00-b6-9c-f5|64&a|18-a6-f7-92-35-da|84")); diff --git a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java index bd1fc71f4..f90497292 100644 --- a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class TzoneProtocolDecoderTest extends ProtocolTest { TzoneProtocolDecoder decoder = new TzoneProtocolDecoder(null); verifyAttributes(decoder, binary( + "545A004B2424041302000000086706003324776413030C0A1A2900180513030C0A1A25080F7E1028CAC830000A000F0000000005000AA53201633D05046000010009AA201737019408973B0032B0260D0A")); + + verifyAttributes(decoder, binary( "545a005b24240406010800000866050033819630120911071824000472bd8e5b0008aac01b07019b04bb002f00040b06161154000e100132ff2006161152000e080096ff4606161151000e1e0101ff1406161156000db6405bff490024469e0d0a")); verifyAttributes(decoder, binary( diff --git a/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java b/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java index d3d0429d6..01d63bfa3 100644 --- a/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java @@ -12,15 +12,15 @@ public class UlbotechFrameDecoderTest extends ProtocolTest { UlbotechFrameDecoder decoder = new UlbotechFrameDecoder(); - assertEquals( + verifyFrame( binary("f8010103515810532780699f7e2e3f010e015ee4c906bde45c00000000008b0304004000000404002c776005060373193622110b00240b00fee8ffff807dffff606d0b00fee9af000000af0000000b00feee7d78807dffffffff100101cc2af8"), decoder.decode(null, null, binary("f8010103515810532780699f7e2e3f010e015ee4c906bde45c00000000008b0304004000000404002c776005060373193622110b00240b00fee8ffff807dffff606d0b00fee9af000000af0000000b00feee7d78807dffffffff100101cc2af8"))); - assertEquals( + verifyFrame( binary("2a545330312c33353430343330353133383934363023"), decoder.decode(null, null, binary("2a545330312c33353430343330353133383934363023"))); - assertEquals( + verifyFrame( binary("f8010108679650230646339de69054010e015ee17506bde2c60000000000ac0304024000000404000009f705060390181422170711310583410c0000310d00312f834131018608040003130a100101136cf8"), decoder.decode(null, null, binary("f8010108679650230646339de69054010e015ee17506bde2c60000000000ac0304024000000404000009f70005060390181422170711310583410c0000310d00312f834131018608040003130a100101136cf8"))); diff --git a/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java index 1c29ccd4a..8c820183b 100644 --- a/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class UlbotechProtocolDecoderTest extends ProtocolTest { "*TS01,868323025245751,134955140317,WFE:0#")); verifyPosition(decoder, binary( + "f801010868323028799515251e10d3010e03b52df8ff99fde500000000270f030402020000040402c62a7e0506057c1929220d060800000000000000000f040071eb621001018536f8"), + position("2019-09-25 11:49:39.000", false, 62.20543, -6.68521)); + + verifyPosition(decoder, binary( "f8010103515810532780699f7e2e3f010e015ee4c906bde45c00000000008b0304004000000404002c776005060373193622110b00240b00fee8ffff807dffff606d0b00fee9af000000af0000000b00feee7d78807dffffffff100101cc2af8")); verifyPosition(decoder, binary( diff --git a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java index dbbe4591f..e43ff322e 100644 --- a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class UproProtocolDecoderTest extends ProtocolTest { @@ -10,6 +11,22 @@ public class UproProtocolDecoderTest extends ProtocolTest { UproProtocolDecoder decoder = new UproProtocolDecoder(null); + verifyAttribute(decoder, buffer( + "*VK200867282036729446,BA&A1759265051877702037465660022210819&B0000000000&W00&G000030&M830&N26&O1706&o11&T0783#"), + Position.KEY_BATTERY_LEVEL, 83.0); + + verifyAttributes(decoder, buffer( + "*VK201867282035754650,AH&B0000000000&W00&M990&N31&Z02&b2&T0458#")); + + verifyAttributes(decoder, buffer( + "*VK201867282035455779,AH&B0000000000&W00&M940&N30&Z02&Y12922&T0268#")); + + verifyPosition(decoder, buffer( + "*VK200867282035455779,BA&A0850065052928902036605660013170719&B0000000000&W00&G000030&M850&N20&O1808&o10&Y12922&T0081#")); + + verifyAttributes(decoder, buffer( + "*VK200867282035455779,BA&X260,6,1016,13931,60;1016,13929,81;1016,14174,82;1016,13930,82&E190717103920&B0100000000&W00&G000030&M900&N23&O0000&o07&Y14014&T0015#")); + verifyPosition(decoder, buffer( "*HQ200861810538000002,BA&A0206033302618209658563620115180119&B0100000040&C6328680=&F0039&R2710&V0036&T09&K50000&N04&P0200#")); diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 539e63253..c5753dc4d 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -16,6 +16,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { WatchProtocolDecoder decoder = new WatchProtocolDecoder(null); verifyPosition(decoder, buffer( + "[3G*2104134718*00A1*UD_WCDMA,161019,134938,A,43.373367,N,71.157615,W,22.0,350.206,279.717,17,28,79,0,0,00000000,1,1,310,410,23999,132013696,28,1,Home2,60:45:cb:cb:34:68,-93,8.263865]")); + + verifyPosition(decoder, buffer( "[ZJ*014111001332708*0075*0064*AL,040418,052156,A,22.536207,N,113.938673,E,0,0,0,5,100,82,1000,50,00100000,1,255,460,0,9340,3663,35]")); verifyPosition(decoder, buffer( @@ -24,6 +27,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, buffer( "[3G*4700609403*0013*bphrt,120,79,73,,,,]")); + verifyAttributes(decoder, buffer( + "[ZJ*357653059860416*0007*000c*BLOOD,109,68]")); + verifyPosition(decoder, buffer( "[3G*8308373902*0080*AL,230817,095346,A,47.083950,N,15.4821850,E,7.60,273.8,0.0,4,15,44,0,0,00200010,2,255,232,1,7605,42530,118,7605,58036,119,0,65.8]")); diff --git a/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java index a0631be3b..798213c7b 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java @@ -9,8 +9,8 @@ public class WatchProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - WatchProtocolEncoder encoder = new WatchProtocolEncoder(); - + WatchProtocolEncoder encoder = new WatchProtocolEncoder(null); + Command command; command = new Command(); @@ -60,7 +60,7 @@ public class WatchProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeTimezone() { - WatchProtocolEncoder encoder = new WatchProtocolEncoder(); + WatchProtocolEncoder encoder = new WatchProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java index 40b0469ea..72e56fb44 100644 --- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java @@ -26,6 +26,9 @@ public class WialonProtocolDecoderTest extends ProtocolTest { "#D#101118;061143;0756.0930;N;12338.6403;E;18.223;99.766;-4.000;10;0.800;NA;NA;NA;NA;101_521347:1:521249,101_521126:1:6593598,101_521127:1:774780,101_521072_21.1:1:0,101_521072_21.2:1:71353;F24A")); verifyPosition(decoder, text( + "99999999#D#101118;061143;0756.0930;N;12338.6403;E;18.223;99.766;-4.000;10;0.800;NA;NA;NA;NA;101_521347:1:521249,101_521126:1:6593598,101_521127:1:774780,101_521072_21.1:1:0,101_521072_21.2:1:71353;F24A")); + + verifyPosition(decoder, text( "#D#151216;135910;5321.1466;N;04441.7929;E;87;156;265.000000;12;1.000000;241;NA;NA;NA;odo:2:0.000000,total_fuel:1:430087,can_fls:1:201,can_taho:1:11623,can_mileage:1:140367515")); verifyPosition(decoder, text( @@ -36,6 +39,10 @@ public class WialonProtocolDecoderTest extends ProtocolTest { position("2013-04-27 20:56:01.000", true, 55.74338, 37.66139)); verifyPosition(decoder, text( + "99999999#SD#270413;205601;5544.6025;N;03739.6834;E;1;2;3;4"), + position("2013-04-27 20:56:01.000", true, 55.74338, 37.66139)); + + verifyPosition(decoder, text( "#SD#021214;065947;2237.7552;N;11404.8851;E;0.000;;170.9;5")); verifyPosition(decoder, text( diff --git a/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java index 8209fc412..41fee2723 100644 --- a/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java @@ -10,7 +10,7 @@ public class WondexProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - WondexProtocolEncoder encoder = new WondexProtocolEncoder(); + WondexProtocolEncoder encoder = new WondexProtocolEncoder(null); Command command = new Command(); command.setDeviceId(2); diff --git a/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java index dd2e939c9..0ff47cad3 100644 --- a/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java @@ -11,14 +11,14 @@ public class XirgoProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - XirgoProtocolEncoder encoder = new XirgoProtocolEncoder(); - + XirgoProtocolEncoder encoder = new XirgoProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_OUTPUT_CONTROL); command.set(Command.KEY_INDEX, 0); command.set(Command.KEY_DATA, 1); - + assertEquals("+XT:7005,2,1", encoder.encodeCommand(command)); } diff --git a/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java index 49476d694..27efbd6db 100644 --- a/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java @@ -11,13 +11,13 @@ public class Xrb28ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionPeriodic() { - Xrb28ProtocolEncoder encoder = new Xrb28ProtocolEncoder(); - + Xrb28ProtocolEncoder encoder = new Xrb28ProtocolEncoder(null); + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_POSITION_PERIODIC); command.set(Command.KEY_FREQUENCY, 300); - + assertEquals("\u00ff\u00ff*SCOS,OM,123456789012345,D1,300#\n", encoder.encodeCommand(null, command)); } @@ -25,7 +25,7 @@ public class Xrb28ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustom() { - Xrb28ProtocolEncoder encoder = new Xrb28ProtocolEncoder(); + Xrb28ProtocolEncoder encoder = new Xrb28ProtocolEncoder(null); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java index f4a78b5bd..6d49f2516 100644 --- a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java @@ -10,6 +10,11 @@ public class Xt2400ProtocolDecoderTest extends ProtocolTest { Xt2400ProtocolDecoder decoder = new Xt2400ProtocolDecoder(null); + decoder.setConfig("\n::wycfg pcr[1] 012801030405060708090a1213c8545657585a656e7d2cd055595d5e71797a7b7c7e7f80818285866b\n"); + + verifyPosition(decoder, binary( + "010ae85be10801a05d52d590030b12d1f9330be9290a0000ff10008b00000000000000000000000000000000000000000000000000000000000000000000000000003839333032363930323031303036363039373733000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000")); + decoder.setConfig("\n:wycfg pcr[0] 001001030406070809570a13121714100565\n"); verifyPosition(decoder, binary( |