From 2a5bf04563ecc8b09f07a0007335bbd111f9c0a2 Mon Sep 17 00:00:00 2001 From: soshial Date: Fri, 10 Sep 2021 09:22:55 +0200 Subject: add support for relative filtering --- setup/default.xml | 13 ++++ src/main/java/org/traccar/config/Keys.java | 16 ++++- .../java/org/traccar/database/DataManager.java | 36 ++++++++++ .../java/org/traccar/handler/FilterHandler.java | 79 ++++++++++++++++------ 4 files changed, 120 insertions(+), 24 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index 0564182c7..e798fcf88 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -22,6 +22,7 @@ true 86400 + false true true @@ -48,6 +49,18 @@ SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime BETWEEN :from AND :to ORDER BY fixTime + + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime = :time LIMIT 1 + + + + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND NOT fixTime lt :time LIMIT 1 ORDER BY fixTime DESC + + + + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime gt :time LIMIT 1 ORDER BY fixTime ASC + + SELECT tc_positions.* FROM tc_positions INNER JOIN tc_devices ON tc_positions.id = tc_devices.positionid; diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6d2296fb1..f7d61a993 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -887,8 +887,19 @@ public final class Keys { Collections.singletonList(KeyType.GLOBAL)); /** - * Time limit for the filtering in seconds. If the time difference between last position and a new one is more than - * this limit, the new position will not be filtered out. + * If FALSE, then filter compares duplicates, distance or period only with the last received location. + * Server expects all locations to come sequentially. + * + * If TRUE, then filter compares duplicates, distance or period with Position's fixTime strictly before and after. + * Server expects locations to come at random order, since tracking device might go offline. + */ + public static final ConfigKey FILTER_RELATIVE = new ConfigKey<>( + "filter.relative", + Collections.singletonList(KeyType.GLOBAL)); + + /** + * Time limit for the filtering in seconds. If the time difference between the last position was received by server + * and a new position is received by server is more than this limit, the new position will not be filtered out. */ public static final ConfigKey FILTER_SKIP_LIMIT = new ConfigKey<>( "filter.skipLimit", @@ -896,6 +907,7 @@ public final class Keys { /** * Enable attributes skipping. Attribute skipping can be enabled in the config or device attributes. + * If position contains any attribute mentioned in "filter.skipAttributes" config key, position is not filtered out. */ public static final ConfigKey FILTER_SKIP_ATTRIBUTES_ENABLE = new ConfigKey<>( "filter.skipAttributes.enable", diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 15137ad91..3f702f78a 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -328,6 +328,42 @@ public class DataManager { .executeQuery(Position.class); } + public Position getPositionByTime(long deviceId, Date date) throws SQLException { + Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPositionByTime")) + .setLong("deviceId", deviceId) + .setDate("time", date) + .executeQuery(Position.class); + if (positions.isEmpty()) { + return null; + } else { + return positions.iterator().next(); + } + } + + public Position getPrevPosition(long deviceId, Date date) throws SQLException { + Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPrevPosition")) + .setLong("deviceId", deviceId) + .setDate("time", date) + .executeQuery(Position.class); + if (positions.isEmpty()) { + return null; + } else { + return positions.iterator().next(); + } + } + + public Position getNextPosition(long deviceId, Date date) throws SQLException { + Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectNextPosition")) + .setLong("deviceId", deviceId) + .setDate("time", date) + .executeQuery(Position.class); + if (positions.isEmpty()) { + return null; + } else { + return positions.iterator().next(); + } + } + public void updateLatestPosition(Position position) throws SQLException { QueryBuilder.create(dataSource, getQuery("database.updateLatestPosition")) .setDate("now", new Date()) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 7cd9153c1..817d6c8ba 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -25,6 +25,9 @@ import org.traccar.config.Keys; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; +import java.sql.SQLException; +import java.util.Date; + @ChannelHandler.Sharable public class FilterHandler extends BaseDataHandler { @@ -40,6 +43,7 @@ public class FilterHandler extends BaseDataHandler { private int filterDistance; private int filterMaxSpeed; private long filterMinPeriod; + private boolean filterRelative; private long skipLimit; private boolean skipAttributes; @@ -54,14 +58,15 @@ public class FilterHandler extends BaseDataHandler { filterDistance = config.getInteger(Keys.FILTER_DISTANCE); filterMaxSpeed = config.getInteger(Keys.FILTER_MAX_SPEED); filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000; + filterRelative = config.getBoolean(Keys.FILTER_RELATIVE); skipLimit = config.getLong(Keys.FILTER_SKIP_LIMIT) * 1000; skipAttributes = config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE); } private boolean filterInvalid(Position position) { return filterInvalid && (!position.getValid() - || position.getLatitude() > 90 || position.getLongitude() > 180 - || position.getLatitude() < -90 || position.getLongitude() < -180); + || position.getLatitude() > 90 || position.getLongitude() > 180 + || position.getLatitude() < -90 || position.getLongitude() < -180); } private boolean filterZero(Position position) { @@ -144,20 +149,13 @@ public class FilterHandler extends BaseDataHandler { StringBuilder filterType = new StringBuilder(); - Position last = null; - if (Context.getIdentityManager() != null) { - last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); - } - + // general filtering if (filterInvalid(position)) { filterType.append("Invalid "); } if (filterZero(position)) { filterType.append("Zero "); } - if (filterDuplicate(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { - filterType.append("Duplicate "); - } if (filterFuture(position)) { filterType.append("Future "); } @@ -167,19 +165,56 @@ public class FilterHandler extends BaseDataHandler { if (filterApproximate(position)) { filterType.append("Approximate "); } - if (filterStatic(position) && !skipLimit(position, last) && !skipAttributes(position)) { - filterType.append("Static "); - } - if (filterDistance(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { - filterType.append("Distance "); - } - if (filterMaxSpeed(position, last)) { - filterType.append("MaxSpeed "); - } - if (filterMinPeriod(position, last)) { - filterType.append("MinPeriod "); - } + if (filterRelative) { + try { + if (filterStatic(position) && !skipAttributes(position)) { + filterType.append("Static "); + } + Date newfixTime = position.getFixTime(); + Position duplicate = Context.getDataManager().getPositionByTime(position.getDeviceId(), newfixTime); + if (filterDuplicate(position, duplicate) && !skipLimit(position, duplicate) + && !skipAttributes(position)) { + filterType.append("Duplicate "); + } + + Position previous = Context.getDataManager().getPrevPosition(position.getDeviceId(), newfixTime); + Position next = Context.getDataManager().getNextPosition(position.getDeviceId(), newfixTime); + if ((filterDistance(position, previous) || filterDistance(next, position)) + && !skipAttributes(position)) { + filterType.append("Distance "); + } + if (filterMaxSpeed(position, previous) || filterMaxSpeed(next, position)) { + filterType.append("MaxSpeed "); + } + if (filterMinPeriod(position, previous) || filterMinPeriod(next, position)) { + filterType.append("MinPeriod "); + } + } catch (SQLException e) { + LOGGER.warn("Error filtering position", e); + } + } else { + Position last = null; + if (Context.getIdentityManager() != null) { + last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); + } + + if (filterDuplicate(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { + filterType.append("Duplicate "); + } + if (filterStatic(position) && !skipLimit(position, last) && !skipAttributes(position)) { + filterType.append("Static "); + } + if (filterDistance(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { + filterType.append("Distance "); + } + if (filterMaxSpeed(position, last)) { + filterType.append("MaxSpeed "); + } + if (filterMinPeriod(position, last)) { + filterType.append("MinPeriod "); + } + } if (filterType.length() > 0) { StringBuilder message = new StringBuilder(); -- cgit v1.2.3 From d9ad81991da306dcae35bb6b7ba7f90c6d6b8725 Mon Sep 17 00:00:00 2001 From: soshial Date: Sun, 12 Sep 2021 05:23:12 +0200 Subject: filtering optimizations --- setup/default.xml | 4 +- src/main/java/org/traccar/config/Keys.java | 7 ++- .../java/org/traccar/handler/FilterHandler.java | 62 +++++++++------------- 3 files changed, 32 insertions(+), 41 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index e798fcf88..54677d845 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -54,11 +54,11 @@ - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND NOT fixTime lt :time LIMIT 1 ORDER BY fixTime DESC + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime lte :time ORDER BY fixTime DESC LIMIT 1 - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime gt :time LIMIT 1 ORDER BY fixTime ASC + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime gt :time ORDER BY fixTime ASC LIMIT 1 diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index f7d61a993..c6a202d2f 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -872,8 +872,11 @@ public final class Keys { Collections.singletonList(KeyType.GLOBAL)); /** - * Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if they're - * marked as valid. Shouldn't be too low. Start testing with values at about 25000. + * Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if Position + * appears valid or if Position `speed` field reported by the device is also within limits. Calculates speed from + * the distance to the previous position and the elapsed time. + * + * Tip: Shouldn't be too low. Start testing with values at about 25000. */ public static final ConfigKey FILTER_MAX_SPEED = new ConfigKey<>( "filter.maxSpeed", diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 817d6c8ba..16e5ae2da 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -146,6 +146,9 @@ public class FilterHandler extends BaseDataHandler { } private boolean filter(Position position) { + if (skipAttributes(position)) { + return false; + } StringBuilder filterType = new StringBuilder(); @@ -165,58 +168,43 @@ public class FilterHandler extends BaseDataHandler { if (filterApproximate(position)) { filterType.append("Approximate "); } - if (filterRelative) { - try { - if (filterStatic(position) && !skipAttributes(position)) { - filterType.append("Static "); - } - - Date newfixTime = position.getFixTime(); - Position duplicate = Context.getDataManager().getPositionByTime(position.getDeviceId(), newfixTime); - if (filterDuplicate(position, duplicate) && !skipLimit(position, duplicate) - && !skipAttributes(position)) { - filterType.append("Duplicate "); - } + if (filterStatic(position)) { + filterType.append("Static "); + } - Position previous = Context.getDataManager().getPrevPosition(position.getDeviceId(), newfixTime); - Position next = Context.getDataManager().getNextPosition(position.getDeviceId(), newfixTime); - if ((filterDistance(position, previous) || filterDistance(next, position)) - && !skipAttributes(position)) { - filterType.append("Distance "); + // relative filtering + if (filterDuplicate || filterDistance != 0 || filterMaxSpeed != 0 || filterMinPeriod != 0) { + Position previous = null; + if (filterRelative) { + try { + Date newFixTime = position.getFixTime(); + previous = Context.getDataManager().getPrevPosition(position.getDeviceId(), newFixTime); + } catch (SQLException e) { + LOGGER.warn("Error filtering position", e); } - if (filterMaxSpeed(position, previous) || filterMaxSpeed(next, position)) { - filterType.append("MaxSpeed "); + } else { + if (Context.getIdentityManager() != null) { + previous = Context.getIdentityManager().getLastPosition(position.getDeviceId()); } - if (filterMinPeriod(position, previous) || filterMinPeriod(next, position)) { - filterType.append("MinPeriod "); - } - } catch (SQLException e) { - LOGGER.warn("Error filtering position", e); } - } else { - Position last = null; - if (Context.getIdentityManager() != null) { - last = Context.getIdentityManager().getLastPosition(position.getDeviceId()); + if (skipLimit(position, previous)) { + return false; } - - if (filterDuplicate(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { + if (filterDuplicate(position, previous)) { filterType.append("Duplicate "); } - if (filterStatic(position) && !skipLimit(position, last) && !skipAttributes(position)) { - filterType.append("Static "); - } - if (filterDistance(position, last) && !skipLimit(position, last) && !skipAttributes(position)) { + if (filterDistance(position, previous)) { filterType.append("Distance "); } - if (filterMaxSpeed(position, last)) { + if (filterMaxSpeed(position, previous)) { filterType.append("MaxSpeed "); } - if (filterMinPeriod(position, last)) { + if (filterMinPeriod(position, previous)) { filterType.append("MinPeriod "); } } - if (filterType.length() > 0) { + if (filterType.length() > 0) { StringBuilder message = new StringBuilder(); message.append("Position filtered by "); message.append(filterType.toString()); -- cgit v1.2.3 From 7a3b106dfc28a6254825b8d664db8181f4bd19f1 Mon Sep 17 00:00:00 2001 From: soshial Date: Sun, 12 Sep 2021 09:31:38 +0200 Subject: improve naming and comments --- setup/default.xml | 7 +---- src/main/java/org/traccar/config/Keys.java | 9 +++--- .../java/org/traccar/database/DataManager.java | 16 ++-------- .../java/org/traccar/handler/FilterHandler.java | 35 ++++++++++++++-------- 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index 54677d845..7ed3e35b2 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -22,7 +22,6 @@ true 86400 - false true true @@ -53,14 +52,10 @@ SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime = :time LIMIT 1 - + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime lte :time ORDER BY fixTime DESC LIMIT 1 - - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime gt :time ORDER BY fixTime ASC LIMIT 1 - - SELECT tc_positions.* FROM tc_positions INNER JOIN tc_devices ON tc_positions.id = tc_devices.positionid; diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index c6a202d2f..a77204175 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -890,11 +890,12 @@ public final class Keys { Collections.singletonList(KeyType.GLOBAL)); /** - * If FALSE, then filter compares duplicates, distance or period only with the last received location. - * Server expects all locations to come sequentially. + * If false, the server expects all locations to come sequentially (for each device). Filter checks for duplicates, + * distance, speed, or time period only against the location that was last received by server. * - * If TRUE, then filter compares duplicates, distance or period with Position's fixTime strictly before and after. - * Server expects locations to come at random order, since tracking device might go offline. + * If true, the server expects locations to come at random order (since tracking device might go offline). + * Filter checks for duplicates, distance, speed, or time period against the preceding Position's. + * Important: setting to true can cause potential performance issues. */ public static final ConfigKey FILTER_RELATIVE = new ConfigKey<>( "filter.relative", diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 3f702f78a..d8401774e 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -340,20 +340,8 @@ public class DataManager { } } - public Position getPrevPosition(long deviceId, Date date) throws SQLException { - Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPrevPosition")) - .setLong("deviceId", deviceId) - .setDate("time", date) - .executeQuery(Position.class); - if (positions.isEmpty()) { - return null; - } else { - return positions.iterator().next(); - } - } - - public Position getNextPosition(long deviceId, Date date) throws SQLException { - Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectNextPosition")) + public Position getPrecedingPosition(long deviceId, Date date) throws SQLException { + Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition")) .setLong("deviceId", deviceId) .setDate("time", date) .executeQuery(Position.class); diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 16e5ae2da..5287a7639 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -146,6 +146,7 @@ public class FilterHandler extends BaseDataHandler { } private boolean filter(Position position) { + if (skipAttributes(position)) { return false; } @@ -173,43 +174,44 @@ public class FilterHandler extends BaseDataHandler { } // relative filtering - if (filterDuplicate || filterDistance != 0 || filterMaxSpeed != 0 || filterMinPeriod != 0) { - Position previous = null; + long deviceId = position.getDeviceId(); + if (filterDuplicate || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { + Position preceding = null; if (filterRelative) { try { Date newFixTime = position.getFixTime(); - previous = Context.getDataManager().getPrevPosition(position.getDeviceId(), newFixTime); + preceding = Context.getDataManager().getPrecedingPosition(deviceId, newFixTime); } catch (SQLException e) { - LOGGER.warn("Error filtering position", e); + LOGGER.warn("Error retrieving preceding position; fallbacking to last received position.", e); + preceding = getLastReceivedPosition(deviceId); } } else { - if (Context.getIdentityManager() != null) { - previous = Context.getIdentityManager().getLastPosition(position.getDeviceId()); - } + preceding = getLastReceivedPosition(deviceId); } - if (skipLimit(position, previous)) { + if (skipLimit(position, preceding)) { return false; } - if (filterDuplicate(position, previous)) { + if (filterDuplicate(position, preceding)) { filterType.append("Duplicate "); } - if (filterDistance(position, previous)) { + if (filterDistance(position, preceding)) { filterType.append("Distance "); } - if (filterMaxSpeed(position, previous)) { + if (filterMaxSpeed(position, preceding)) { filterType.append("MaxSpeed "); } - if (filterMinPeriod(position, previous)) { + if (filterMinPeriod(position, preceding)) { filterType.append("MinPeriod "); } } if (filterType.length() > 0) { + StringBuilder message = new StringBuilder(); message.append("Position filtered by "); message.append(filterType.toString()); message.append("filters from device: "); - message.append(Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId()); + message.append(Context.getIdentityManager().getById(deviceId).getUniqueId()); LOGGER.info(message.toString()); return true; @@ -218,6 +220,13 @@ public class FilterHandler extends BaseDataHandler { return false; } + private Position getLastReceivedPosition(long deviceId) { + if (Context.getIdentityManager() != null) { + return Context.getIdentityManager().getLastPosition(deviceId); + } + return null; + } + @Override protected Position handlePosition(Position position) { if (filter(position)) { -- cgit v1.2.3 From fd91d6bbb189b091799708a4d3f4e9d9ca114763 Mon Sep 17 00:00:00 2001 From: soshial Date: Mon, 13 Sep 2021 08:21:35 +0200 Subject: remove comments --- setup/default.xml | 4 ---- src/main/java/org/traccar/database/DataManager.java | 12 ------------ src/main/java/org/traccar/handler/FilterHandler.java | 2 -- 3 files changed, 18 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index 7ed3e35b2..419eaef45 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -48,10 +48,6 @@ SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime BETWEEN :from AND :to ORDER BY fixTime - - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime = :time LIMIT 1 - - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime lte :time ORDER BY fixTime DESC LIMIT 1 diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index d8401774e..15c67cb74 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -328,18 +328,6 @@ public class DataManager { .executeQuery(Position.class); } - public Position getPositionByTime(long deviceId, Date date) throws SQLException { - Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPositionByTime")) - .setLong("deviceId", deviceId) - .setDate("time", date) - .executeQuery(Position.class); - if (positions.isEmpty()) { - return null; - } else { - return positions.iterator().next(); - } - } - public Position getPrecedingPosition(long deviceId, Date date) throws SQLException { Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition")) .setLong("deviceId", deviceId) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 5287a7639..6331ff773 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -153,7 +153,6 @@ public class FilterHandler extends BaseDataHandler { StringBuilder filterType = new StringBuilder(); - // general filtering if (filterInvalid(position)) { filterType.append("Invalid "); } @@ -173,7 +172,6 @@ public class FilterHandler extends BaseDataHandler { filterType.append("Static "); } - // relative filtering long deviceId = position.getDeviceId(); if (filterDuplicate || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { Position preceding = null; -- cgit v1.2.3 From a6ccfd679686cfb62f8390334229ba7fdf92eb42 Mon Sep 17 00:00:00 2001 From: soshial Date: Mon, 13 Sep 2021 21:42:56 +0200 Subject: fix SQL syntax in XML --- setup/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/default.xml b/setup/default.xml index 419eaef45..e427d05e5 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -49,7 +49,7 @@ - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime lte :time ORDER BY fixTime DESC LIMIT 1 + SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime <= :time ORDER BY fixTime DESC LIMIT 1 -- cgit v1.2.3 From c345945c36b4c93f2f436cf61f89495577d072ea Mon Sep 17 00:00:00 2001 From: soshial Date: Sat, 18 Sep 2021 21:15:24 +0200 Subject: improve SQL query --- src/main/java/org/traccar/database/DataManager.java | 9 ++------- src/main/java/org/traccar/handler/FilterHandler.java | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 15c67cb74..75ec70ea7 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -329,15 +329,10 @@ public class DataManager { } public Position getPrecedingPosition(long deviceId, Date date) throws SQLException { - Collection positions = QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition")) + return QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition")) .setLong("deviceId", deviceId) .setDate("time", date) - .executeQuery(Position.class); - if (positions.isEmpty()) { - return null; - } else { - return positions.iterator().next(); - } + .executeQuerySingle(Position.class); } public void updateLatestPosition(Position position) throws SQLException { diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 6331ff773..19d72d8a1 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -74,7 +74,7 @@ public class FilterHandler extends BaseDataHandler { } private boolean filterDuplicate(Position position, Position last) { - if (filterDuplicate && last != null && position.getFixTime().equals(last.getFixTime())) { + if (filterDuplicate && last != null && position.getFixTime().getTime() == last.getFixTime().getTime()) { for (String key : position.getAttributes().keySet()) { if (!last.getAttributes().containsKey(key)) { return false; -- cgit v1.2.3 From 83cff6dd3876fa81d3f3257f1fb3f72cbdf38e70 Mon Sep 17 00:00:00 2001 From: soshial Date: Tue, 28 Sep 2021 11:51:38 +0200 Subject: shorten IF clause --- src/main/java/org/traccar/handler/FilterHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 19d72d8a1..6331ff773 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -74,7 +74,7 @@ public class FilterHandler extends BaseDataHandler { } private boolean filterDuplicate(Position position, Position last) { - if (filterDuplicate && last != null && position.getFixTime().getTime() == last.getFixTime().getTime()) { + if (filterDuplicate && last != null && position.getFixTime().equals(last.getFixTime())) { for (String key : position.getAttributes().keySet()) { if (!last.getAttributes().containsKey(key)) { return false; -- cgit v1.2.3 From d9b8f1e2c0a61438136954671c91445bbae6b76e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Nov 2021 17:04:26 -0800 Subject: Enable LocationIQ by default --- debug.xml | 3 --- setup/default.xml | 6 ++++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/debug.xml b/debug.xml index 796442364..f9515bb2b 100644 --- a/debug.xml +++ b/debug.xml @@ -10,9 +10,6 @@ true true - false - ban - true org.h2.Driver diff --git a/setup/default.xml b/setup/default.xml index f314413f1..407f3f8bf 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -14,8 +14,10 @@ ./web false - false - google + true + nominatim + https://us1.locationiq.com/v1/reverse.php + pk.b34237342901fc175252c790d1674dcc info ./logs/tracker-server.log -- cgit v1.2.3 From 0fea1a39bea08a43771fc08becdf5d7f2f392531 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Nov 2021 17:19:13 -0800 Subject: Fix status decoding --- .../java/org/traccar/protocol/MobilogixProtocolDecoder.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index f3b70e40c..86c89e336 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -47,9 +47,9 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { .number("(d+.d+)") // battery .groupBegin() .text(",") - .number("(d)") // valid + .number("(d)") // satellites .number("(d)") // rssi - .number("(d),") // satellites + .number("(d),") // valid .number("(-?d+.d+),") // latitude .number("(-?d+.d+),") // longitude .number("(d+.?d*),") // speed @@ -127,12 +127,12 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext(7)) { + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_RSSI, 6 * parser.nextInt() - 111); + position.setValid(parser.nextInt() > 0); position.setFixTime(position.getDeviceTime()); - position.set(Position.KEY_RSSI, parser.nextInt()); - position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.setLatitude(parser.nextDouble()); position.setLongitude(parser.nextDouble()); position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); -- cgit v1.2.3 From 610bd8d84705b5cfa43f2bcf50d6f0c841ecf260 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Nov 2021 17:52:29 -0800 Subject: Add custom frame decoder --- .../traccar/protocol/TechtoCruzFrameDecoder.java | 44 ++++++++++++++++++++++ .../org/traccar/protocol/TechtoCruzProtocol.java | 3 +- .../protocol/TechtoCruzFrameDecoderTest.java | 25 ++++++++++++ .../protocol/TechtoCruzProtocolDecoderTest.java | 3 ++ 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java create mode 100644 src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java diff --git a/src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java b/src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java new file mode 100644 index 000000000..8b9152e8b --- /dev/null +++ b/src/main/java/org/traccar/protocol/TechtoCruzFrameDecoder.java @@ -0,0 +1,44 @@ +/* + * Copyright 2021 Anton Tananaev (anton@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 java.nio.charset.StandardCharsets; + +public class TechtoCruzFrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + int lengthStart = buf.readerIndex() + 3; + int lengthEnd = buf.indexOf(lengthStart, buf.writerIndex(), (byte) ','); + if (lengthEnd > 0) { + int length = lengthStart + + Integer.parseInt(buf.toString(lengthStart, lengthEnd - lengthStart, StandardCharsets.US_ASCII)); + if (buf.readableBytes() >= length) { + return buf.readRetainedSlice(length); + } + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java index 890a8abb1..a217ea738 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java @@ -15,7 +15,6 @@ */ 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; @@ -28,7 +27,7 @@ public class TechtoCruzProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); + pipeline.addLast(new TechtoCruzFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new TechtoCruzProtocolDecoder(TechtoCruzProtocol.this)); diff --git a/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java new file mode 100644 index 000000000..dc4afb784 --- /dev/null +++ b/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java @@ -0,0 +1,25 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +import static org.junit.Assert.assertEquals; + +public class TechtoCruzFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new TechtoCruzFrameDecoder(); + + assertEquals( + buffer("$$A35,RESPO|G33|8612345678910|CRUZ,*E3"), + decoder.decode(null, null, buffer("$$A35,RESPO|G33|8612345678910|CRUZ,*E3"))); + + assertEquals( + buffer("$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6"), + decoder.decode(null, null, buffer("$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6"))); + + } + +} diff --git a/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java index 8f4a7915d..4cef682b4 100644 --- a/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class TechtoCruzProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6")); + verifyNull(decoder, text( + "$$A35,RESPO|G33|8612345678910|CRUZ,*E3")); + } } -- cgit v1.2.3 From a1cc21184376a354088376e5e8b5fd55b15df9b9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Nov 2021 23:33:54 -0800 Subject: Decode extension types --- .../traccar/protocol/HuabaoProtocolDecoder.java | 71 ++++++++++++++++++++++ .../protocol/HuabaoProtocolDecoderTest.java | 6 ++ 2 files changed, 77 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 871410c44..af8c5ba09 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -266,6 +266,72 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return null; } + private void decodeExtension(Position position, ByteBuf buf, int endIndex) { + while (buf.readerIndex() < endIndex) { + int type = buf.readUnsignedByte(); + int length = buf.readUnsignedByte(); + switch (type) { + case 0x01: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100L); + break; + case 0x02: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.1); + break; + case 0x03: + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); + break; + case 0x80: + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); + break; + case 0x81: + position.set(Position.KEY_RPM, buf.readUnsignedShort()); + break; + case 0x82: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); + break; + case 0x83: + position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); + break; + case 0x84: + position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); + break; + case 0x85: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort()); + break; + case 0x86: + position.set("intakeTemp", buf.readUnsignedByte() - 40); + break; + case 0x87: + position.set("intakeFlow", buf.readUnsignedShort()); + break; + case 0x88: + position.set("intakePressure", buf.readUnsignedByte()); + break; + case 0x89: + position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); + break; + case 0x8B: + position.set(Position.KEY_VIN, buf.readCharSequence(17, StandardCharsets.US_ASCII).toString()); + break; + case 0x8C: + position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 100L); + break; + case 0x8D: + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 1000L); + break; + case 0x8E: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); + break; + case 0xCC: + position.set(Position.KEY_ICCID, buf.readCharSequence(20, StandardCharsets.US_ASCII).toString()); + break; + default: + buf.skipBytes(length); + break; + } + } + } + private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { Position position = new Position(getProtocolName()); @@ -346,6 +412,11 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, Integer.parseInt(lockStatus.substring(2, 5)) * 0.01); } break; + case 0x80: + buf.readUnsignedByte(); // content + endIndex = buf.writerIndex() - 2; + decodeExtension(position, buf, endIndex); + break; case 0x91: position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.1); position.set(Position.KEY_RPM, buf.readUnsignedShort()); diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index bf94c5dc5..63ac0ce16 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,12 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7E01000021013345678906000F002C012F373031313142534A2D4D3742203030303030303001D4C1423838383838B47E")); + verifyPosition(decoder, binary( + "7E020000830191715904370A2E00000000800000030158991806CA0FEB00040000010D211108194050010400000003CC14383938363034373831303230373033313836303830011A8001AA810213888202007A8301148401AA8502189B8601338702007D028801338901148A0200998B1131323334353637383941424344454647488C04000200A88D0200828E0114A0002E7E")); + + verifyPosition(decoder, binary( + "7e0200007c0191718447540dcd000000008000000b029eabc204ba78510004000000042111182321120104000017f6cc14383933303237323037303339333033383732373130011d800134810204718202008283010e84017b85021ae986012f870201788901038b114a4e31424a314352364b573333363533358c040008dcb68d02018c8e013da000c07e")); + verifyNotNull(decoder, binary( "7e207002940121523001530047210927151009000e002d80ac210927151010000e002d80ab210927151011000e002d80ac210927151012000e002e80ab210927151013000e002d80ab210927151014000e002d80ab210927151015000e002d80ab210927151016000e002d80aa210927151017000e002e80ab210927151018000e002d80ab210927151019000e002e80ac210927151020000e002d80ab210927151021000e002d80ab210927151022000d002d80ac210927151023000e002d80ac210927151024000e002e80ab210927151025000e002e80b0210927151026000e002e80ab210927151027000e002d80ab210927151028000e002e80b0210927151029000e002d80b0210927151030000e002e80ab210927151031000e002d80ab210927151032000e002d80aa210927151033000e002d80ab210927151034000e002d80ab210927151035000e002d80ab210927151036000e002d80ab210927151037000e002d80ab210927151038000e002d80b0210927151039000d002e80aa210927151040000e002d80ab210927151041000e002d80a5210927151042000e002e80ab210927151043000e002d80aa210927151044000e002d80ab210927151045000e002d80ab210927151046000e002d80ac210927151047000e002e80ab210927151048000e002e80a5210927151049000e002d80ab210927151050000e002d80ab210927151051000e002d80ab210927151052000e002d80ab210927151053000e002d80aa210927151054000e002e80b0210927151055000e002e80ab210927151056000e002d80ac210927151057000e002e80ab210927151058000e002d80ab210927151059000e002e80ab210927151100000e002d80ab210927151101000e002e80aa210927151102000e002d80a6210927151103000e002e80a5847e")); -- cgit v1.2.3 From 091bbdebf7e8fc0e4e8623141bb25b6ceb18371a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 26 Nov 2021 19:07:08 -0800 Subject: Add FlexAPI protocol support --- setup/default.xml | 1 + .../java/org/traccar/protocol/FlexApiProtocol.java | 37 ++++++++++ .../traccar/protocol/FlexApiProtocolDecoder.java | 85 ++++++++++++++++++++++ .../protocol/FlexApiProtocolDecoderTest.java | 33 +++++++++ 4 files changed, 156 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/FlexApiProtocol.java create mode 100644 src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 407f3f8bf..54e8d495e 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -302,5 +302,6 @@ 5232 5233 5234 + 5235 diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java new file mode 100644 index 000000000..a1e741eee --- /dev/null +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -0,0 +1,37 @@ +/* + * Copyright 2021 Anton Tananaev (anton@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 org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; + +public class FlexApiProtocol extends BaseProtocol { + + public FlexApiProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new LineBasedFrameDecoder(1024)); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new FlexApiProtocolDecoder(FlexApiProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java new file mode 100644 index 000000000..d2b3c6960 --- /dev/null +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -0,0 +1,85 @@ +/* + * Copyright 2021 Anton Tananaev (anton@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.model.Position; + +import javax.json.Json; +import javax.json.JsonObject; +import java.io.StringReader; +import java.net.SocketAddress; +import java.util.Date; + +public class FlexApiProtocolDecoder extends BaseProtocolDecoder { + + public FlexApiProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String message = (String) msg; + JsonObject root = Json.createReader(new StringReader(message.substring(1, message.length() - 2))).readObject(); + + String topic = root.getString("topic"); + String clientId = topic.substring(3, topic.indexOf('/', 3)); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, clientId); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + JsonObject payload = root.getJsonObject("payload"); + + if (topic.contains("gnss")) { + + position.setValid(true); + position.setTime(new Date(payload.getInt("time") * 1000L)); + position.setLatitude(payload.getJsonNumber("lat").doubleValue()); + position.setLongitude(payload.getJsonNumber("log").doubleValue()); + position.setAltitude(payload.getJsonNumber("gnss.altitude").doubleValue()); + position.setSpeed(payload.getJsonNumber("gnss.speed").doubleValue()); + position.setCourse(payload.getJsonNumber("gnss.heading").doubleValue()); + + position.set(Position.KEY_SATELLITES, payload.getInt("gnss.num_sv")); + + } else if (topic.contains("obd")) { + + getLastLocation(position, new Date(payload.getInt("obd.ts") * 1000L)); + + position.set(Position.KEY_OBD_SPEED, payload.getJsonNumber("obd.speed").doubleValue()); + position.set(Position.KEY_OBD_ODOMETER, payload.getInt("obd.odo")); + position.set(Position.KEY_RPM, payload.getInt("obd.rpm")); + position.set(Position.KEY_VIN, payload.getString("obd.vin")); + + } else { + + return null; + + } + + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java new file mode 100644 index 000000000..04163294f --- /dev/null +++ b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java @@ -0,0 +1,33 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class FlexApiProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new FlexApiProtocolDecoder(null); + + verifyAttributes(decoder, text( + "${\"topic\":\"v1/VF3102021111601/obd/info\",\"payload\":{\"obd.ts\":1637225390,\"obd.speed\":0,\"obd.f_lvl\":null,\"obd.odo\":0,\"obd.e_hours\":0,\"obd.ab_level\":null,\"obd.mil\":0,\"obd.dtcs\":null,\"obd.rpm\":0,\"obd.e_load\":null,\"obd.c_temp\":-40,\"obd.o_temp\":-273,\"obd.a_temp\":null,\"obd.f_press\":null,\"obd.t_pos\":0,\"obd.b_volt\":null,\"obd.up_time\":null,\"obd.m_dist\":null,\"obd.m_time\":null,\"obd.d_dist\":null,\"obd.d_time\":null,\"obd.vin\":\"NLVIN123456789ABC\",\"obd.brake\":0,\"obd.parking\":0,\"obd.s_w_angle\":null,\"obd.f_rate\":0,\"obd.f_econ\":0,\"obd.a_pos\":null,\"obd.t_dist\":0,\"obd.b_press\":null,\"obd.f_r_press\":null,\"obd.i_temp\":null,\"obd.i_press\":null,\"obd.r_torque\":null,\"obd.f_torque\":null,\"obd.max_avl_torque\":null,\"obd.a_torque\":-125,\"obd.d_e_f_vol\":null,\"obd.mf_mon\":null,\"obd.f_s_mon\":null,\"obd.c_c_mon\":null,\"obd.c_mon\":null,\"obd.h_c_mon\":null,\"obd.e_s_mon\":null,\"obd.s_a_s_mon\":null,\"obd.a_s_r_mon\":null,\"obd.e_g_s_mon\":null,\"obd.e_g_s_h_mon\":null,\"obd.e_v_s_mon\":null,\"obd.c_s_a_s_mon\":null,\"obd.b_p_c_s_mon\":null,\"obd.dpf_mon\":null,\"obd.n_c_mon\":null,\"obd.nmhc_mon\":null,\"obd.o_s_mon\":null,\"obd.o_s_h_mon\":null,\"obd.pf_mon\":null}}xx")); + + verifyPosition(decoder, text( + "${\"topic\":\"v1/VF3102021111601/gnss/info\",\"payload\":{\"time\":1637225390,\"lat\":30.587942,\"log\":104.053543,\"gnss.altitude\":480.399994,\"gnss.speed\":0,\"gnss.heading\":0,\"gnss.hdop\":0.900000,\"gnss.fix\":4,\"gnss.num_sv\":11}}xx")); + + verifyNull(decoder, text( + "${\"topic\":\"v1/VF3102021111601/motion/info\",\"payload\":{\"motion.ts\":1637225450,\"motion.ax\":0.009272,\"motion.ay\":0.278404,\"motion.az\":-0.941596,\"motion.gx\":0.420000,\"motion.gy\":-0.490000,\"motion.gz\":0.140000}}xx")); + + verifyNull(decoder, text( + "${\"topic\":\"v1/VF3102021111601/sysinfo/info\",\"payload\":{\"sysinfo.ts\":1637224740,\"sysinfo.model_name\":\"310\",\"sysinfo.oem_name\":\"inhand\",\"sysinfo.serial_number\":\"VF3102021111601\",\"sysinfo.firmware_version\":\"VT3_V1.1.32\",\"sysinfo.product_number\":\"FQ58\",\"sysinfo.description\":\"www.inhand.com.cn\"}}xx")); + + verifyNull(decoder, text( + "${\"topic\":\"v1/VF3102021111601/io/info\",\"payload\":{\"io.ts\":1637227722,\"io.AI1\":0,\"io.DI1\":1,\"io.DI2\":0,\"io.DI3\":0,\"io.DI4\":0,\"io.DI1_pullup\":0,\"io.DI2_pullup\":0,\"io.DI3_pullup\":0,\"io.DI4_pullup\":0,\"io.DO1\":0,\"io.DO2\":0,\"io.DO3\":0,\"io.IGT\":1}}xx")); + + verifyNull(decoder, text( + "${\"topic\":\"v1/VF3102021111601/cellular1/info\",\"payload\":{\"modem1.ts\":1637225330,\"modem1.imei\":\"863674047324999\",\"modem1.imsi\":\"460111150414721\",\"modem1.iccid\":\"89860319482086580401\",\"modem1.phone_num\":\"\",\"modem1.signal_lvl\":25,\"modem1.reg_status\":1,\"modem1.operator\":\"46011\",\"modem1.network\":3,\"modem1.lac\":\"EA00\",\"modem1.cell_id\":\"E779B81\",\"modem1.rssi\":0,\"modem1.rsrp\":0,\"modem1.rsrq\":0,\"cellular1.status\":3,\"cellular1.ip\":\"10.136.143.193\",\"cellular1.netmask\":\"255.255.255.255\",\"cellular1.gateway\":\"10.64.64.64\",\"cellular1.dns1\":\"223.5.5.5\",\"cellular1.up_at\":450}}xx")); + + } + +} -- cgit v1.2.3 From 542e70a1d4aca4fa3260b86993a1b3558d81e508 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 28 Nov 2021 21:49:13 -0800 Subject: Support fault codes --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 4 ++++ src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index af8c5ba09..297f26f51 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -322,6 +322,10 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x8E: position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); break; + case 0xA0: + String codes = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + position.set(Position.KEY_DTCS, codes.replace(',', ' ')); + break; case 0xCC: position.set(Position.KEY_ICCID, buf.readCharSequence(20, StandardCharsets.US_ASCII).toString()); break; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 63ac0ce16..238799fac 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7E01000021013345678906000F002C012F373031313142534A2D4D3742203030303030303001D4C1423838383838B47E")); + verifyAttribute(decoder, binary( + "7e0200008e01917159043700b300000000800000030158990606ca0fd7000400000000211129111705010400000000cc14383938363037423831303230393031363239363830010d8001aa81021388820200858301148401aa8502189b8601338702007e8801338901148a0200998b1131323334353637383941424344454647488c04000200a88d0200828e0114a00b50353338662c5530323966037e"), + Position.KEY_DTCS, "P538f U029f"); + verifyPosition(decoder, binary( "7E020000830191715904370A2E00000000800000030158991806CA0FEB00040000010D211108194050010400000003CC14383938363034373831303230373033313836303830011A8001AA810213888202007A8301148401AA8502189B8601338702007D028801338901148A0200998B1131323334353637383941424344454647488C04000200A88D0200828E0114A0002E7E")); -- cgit v1.2.3 From 480aee67810d6cd39e1d8efcdc2bed9b52789292 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 29 Nov 2021 20:49:25 -0800 Subject: Update RSSI decoding --- src/main/java/org/traccar/protocol/BceProtocolDecoder.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java index c1a69981d..535827f3c 100644 --- a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java @@ -90,11 +90,13 @@ public class BceProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(mask, 14)) { - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShortLE(), buf.readUnsignedByte(), - buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), - buf.readUnsignedByte()))); - buf.readUnsignedByte(); + int mcc = buf.readUnsignedShortLE(); + int mnc = buf.readUnsignedByte(); + int lac = buf.readUnsignedShortLE(); + int cid = buf.readUnsignedShortLE(); + buf.readUnsignedByte(); // time advance + int rssi = -buf.readUnsignedByte(); + position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid, rssi))); } } -- cgit v1.2.3 From 9bb414a077ec263de5bc89948c3c104d46c968e9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 30 Nov 2021 21:04:41 -0800 Subject: Fix archive decoding --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 297f26f51..aa85ea061 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -581,7 +581,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < count; i++) { int endIndex = buf.readUnsignedShort() + buf.readerIndex(); Position position = decodeLocation(deviceSession, buf); - if (locationType == 0) { + if (locationType > 0) { position.set(Position.KEY_ARCHIVE, true); } positions.add(position); -- cgit v1.2.3 From 97bca437b8e92d69a71e753d969a758064f7ddbd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 30 Nov 2021 21:23:46 -0800 Subject: Support JT701D acknowledgement --- .../java/org/traccar/protocol/Jt600ProtocolDecoder.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index 37c1674d4..dc4bd3486 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -141,6 +141,8 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { int version = BitUtil.from(buf.readUnsignedByte(), 4); buf.readUnsignedShort(); // length + boolean responseRequired = false; + while (buf.readableBytes() > 1) { Position position = new Position(getProtocolName()); @@ -160,6 +162,9 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, BitUtil.check(status, 2) ? Position.ALARM_GEOFENCE_EXIT : null); position.set(Position.KEY_ALARM, BitUtil.check(status, 3) ? Position.ALARM_POWER_CUT : null); position.set(Position.KEY_ALARM, BitUtil.check(status, 4) ? Position.ALARM_VIBRATION : null); + if (BitUtil.check(status, 5)) { + responseRequired = true; + } position.set(Position.KEY_BLOCKED, BitUtil.check(status, 7)); position.set(Position.KEY_ALARM, BitUtil.check(status, 8 + 3) ? Position.ALARM_LOW_BATTERY : null); position.set(Position.KEY_ALARM, BitUtil.check(status, 8 + 6) ? Position.ALARM_FAULT : null); @@ -232,7 +237,15 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { } - buf.readUnsignedByte(); // index + int index = buf.readUnsignedByte(); + + if (channel != null && responseRequired) { + if (protocolVersion < 0x19) { + channel.writeAndFlush(new NetworkMessage("(P35)", remoteAddress)); + } else { + channel.writeAndFlush(new NetworkMessage("(P69,0," + index + ")", remoteAddress)); + } + } return positions; } -- cgit v1.2.3 From ff97d923cf7f06ed2a985b67b182943b2ff56613 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 1 Dec 2021 23:15:22 -0800 Subject: Update LocationIQ keys --- setup/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/default.xml b/setup/default.xml index 54e8d495e..83788b19b 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -17,7 +17,7 @@ true nominatim https://us1.locationiq.com/v1/reverse.php - pk.b34237342901fc175252c790d1674dcc + pk.689d849289c8c63708068b2ff1f63b2d info ./logs/tracker-server.log -- cgit v1.2.3 From bff2f2d61878390827ed452bd8a6c4e48f89083b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Dec 2021 20:39:23 -0800 Subject: Fix temperature decoding --- src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 7f7873e50..d56826cd9 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -232,6 +232,11 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return null; } + private double decodeBleTemp(ByteBuf buf) { + int value = buf.readUnsignedShort(); + return (BitUtil.check(value, 15) ? -BitUtil.to(value, 15) : BitUtil.to(value, 15)) * 0.01; + } + private Position decodeBle( Channel channel, DeviceSession deviceSession, ByteBuf buf, int type, int index, ByteBuf imei) { @@ -281,7 +286,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", buf.readUnsignedByte() * 0.01 + 2); buf.readUnsignedByte(); // battery level - position.set("tag" + i + "Temp", buf.readUnsignedShort() * 0.01); + position.set("tag" + i + "Temp", decodeBleTemp(buf)); position.set("tag" + i + "Humidity", buf.readUnsignedShort() * 0.01); position.set("tag" + i + "LightSensor", buf.readUnsignedShort()); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); @@ -290,7 +295,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", buf.readUnsignedByte() * 0.01 + 2); buf.readUnsignedByte(); // battery level - position.set("tag" + i + "Temp", buf.readUnsignedShort() * 0.01); + position.set("tag" + i + "Temp", decodeBleTemp(buf)); position.set("tag" + i + "Door", buf.readUnsignedByte() > 0); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); break; -- cgit v1.2.3 From d7aabe103f4a560353d9ed16d541540b834c5e19 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Dec 2021 08:28:19 -0800 Subject: Additional alarm field --- .../org/traccar/protocol/TopinProtocolDecoder.java | 29 ++++++++++++++-------- .../traccar/protocol/TopinProtocolDecoderTest.java | 4 +++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java index 267bce562..40a583f2a 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -93,6 +93,19 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { return negative ? -result : result; } + private String decodeAlarm(int alarms) { + if (BitUtil.check(alarms, 0)) { + return Position.ALARM_VIBRATION; + } + if (BitUtil.check(alarms, 1)) { + return Position.ALARM_OVERSPEED; + } + if (BitUtil.check(alarms, 4)) { + return Position.ALARM_LOW_POWER; + } + return null; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -158,17 +171,7 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { if (buf.readableBytes() >= 5) { position.setAltitude(buf.readShort()); - - int alarms = buf.readUnsignedByte(); - if (BitUtil.check(alarms, 0)) { - position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); - } - if (BitUtil.check(alarms, 1)) { - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - } - if (BitUtil.check(alarms, 4)) { - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - } + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); } ByteBuf content = Unpooled.buffer(); @@ -246,6 +249,10 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); } + if (buf.readableBytes() > 2) { + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + } + position.setNetwork(network); ByteBuf content = Unpooled.buffer(); diff --git a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java index 331be974c..e8da93006 100644 --- a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class TopinProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780d0103593390754169634d0d0a")); + verifyAttribute(decoder, binary( + "7878006921120412565802010601071e4a9764071e4a9864010d0a"), + Position.KEY_ALARM, Position.ALARM_VIBRATION); + verifyAttribute(decoder, binary( "787801940D0A"), Position.KEY_ALARM, Position.ALARM_VIBRATION); -- cgit v1.2.3 From c0c7077ab4dd21382d880a250f424d093da26d7b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 5 Dec 2021 23:27:38 -0800 Subject: Make property final --- src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java index f71620d8a..33cd84a47 100644 --- a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java @@ -25,7 +25,7 @@ import javax.ws.rs.client.InvocationCallback; public class UniversalGeolocationProvider implements GeolocationProvider { - private String url; + private final String url; public UniversalGeolocationProvider(String url, String key) { this.url = url + "?key=" + key; -- cgit v1.2.3 From 955c1abe0753a030846db552c6eea262d7d326d1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Dec 2021 22:05:37 -0800 Subject: Alternative alarm type set --- .../org/traccar/protocol/T800xProtocolDecoder.java | 26 ++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index d56826cd9..b15688df0 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -77,7 +77,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } - private String decodeAlarm(int value) { + private String decodeAlarm1(int value) { switch (value) { case 1: return Position.ALARM_POWER_CUT; @@ -107,6 +107,28 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } + private String decodeAlarm2(int value) { + switch (value) { + case 1: + case 4: + return Position.ALARM_REMOVING; + case 2: + return Position.ALARM_TAMPERING; + case 3: + return Position.ALARM_SOS; + case 5: + return Position.ALARM_FALL_DOWN; + case 6: + return Position.ALARM_LOW_BATTERY; + case 14: + return Position.ALARM_GEOFENCE_ENTER; + case 15: + return Position.ALARM_GEOFENCE_EXIT; + default: + return null; + } + } + private Date readDate(ByteBuf buf) { return new DateBuilder() .setYear(BcdUtil.readInteger(buf, 2)) @@ -374,7 +396,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } int alarm = buf.readUnsignedByte(); - position.set(Position.KEY_ALARM, decodeAlarm(alarm)); + position.set(Position.KEY_ALARM, header != 0x2727 ? decodeAlarm1(alarm) : decodeAlarm2(alarm)); if (header != 0x2727) { -- cgit v1.2.3 From b845750ff5be762098b8d246fbb2ca4f35b7e9c5 Mon Sep 17 00:00:00 2001 From: telubato Date: Wed, 8 Dec 2021 15:58:56 +0000 Subject: Add new IO's --- .../org/traccar/protocol/RuptelaProtocolDecoder.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 5c2885a8b..2812d22ff 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -102,6 +102,12 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 5: position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); break; + case 29: + position.set(Position.KEY_POWER, readValue(buf, length, false)); + break; + case 30: + position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); + break; case 74: position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); break; @@ -110,22 +116,19 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { case 80: position.set(Position.PREFIX_TEMP + (id - 78), readValue(buf, length, true) * 0.1); break; - case 198: - if (readValue(buf, length, false) > 0) { - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - } - break; - case 199: - case 200: + case 134: if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); } break; - case 201: + case 136: if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); } break; + case 197: + position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.125); + break; default: position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); break; -- cgit v1.2.3 From 21eab8d6d4ce37c1d6bf20e9dbb897fabf9a0eea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 8 Dec 2021 23:16:28 -0800 Subject: Increase frame limit --- src/main/java/org/traccar/protocol/FlexApiProtocol.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java index a1e741eee..bc6a49907 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -27,7 +27,7 @@ public class FlexApiProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); + pipeline.addLast(new LineBasedFrameDecoder(5120)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new FlexApiProtocolDecoder(FlexApiProtocol.this)); } -- cgit v1.2.3 From f020e0472d4544c7f968d8fb2504ad8e85174a49 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Dec 2021 19:23:38 -0800 Subject: Handle missing attributes --- .../org/traccar/protocol/FlexApiProtocolDecoder.java | 16 ++++++++++++---- .../org/traccar/protocol/FlexApiProtocolDecoderTest.java | 3 +++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index d2b3c6960..25a8f7090 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -68,10 +68,18 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, new Date(payload.getInt("obd.ts") * 1000L)); - position.set(Position.KEY_OBD_SPEED, payload.getJsonNumber("obd.speed").doubleValue()); - position.set(Position.KEY_OBD_ODOMETER, payload.getInt("obd.odo")); - position.set(Position.KEY_RPM, payload.getInt("obd.rpm")); - position.set(Position.KEY_VIN, payload.getString("obd.vin")); + if (payload.containsKey("obd.speed")) { + position.set(Position.KEY_OBD_SPEED, payload.getJsonNumber("obd.speed").doubleValue()); + } + if (payload.containsKey("obd.odo")) { + position.set(Position.KEY_OBD_ODOMETER, payload.getInt("obd.odo")); + } + if (payload.containsKey("obd.rpm")) { + position.set(Position.KEY_RPM, payload.getInt("obd.rpm")); + } + if (payload.containsKey("obd.vin")) { + position.set(Position.KEY_VIN, payload.getString("obd.vin")); + } } else { diff --git a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java index 04163294f..83f36f394 100644 --- a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class FlexApiProtocolDecoderTest extends ProtocolTest { var decoder = new FlexApiProtocolDecoder(null); + verifyAttributes(decoder, text( + "${\"topic\":\"v1/VF3102029000003/obd/info\",\"payload\":{\"obd.ts\":1639037377,\"obd.speed\":211,\"obd.f_lvl\":50.196079,\"obd.mil\":0,\"obd.dtcs\":0,\"obd.rpm\":14531.250000,\"obd.e_load\":50.980392,\"obd.c_temp\":118,\"obd.o_temp\":56,\"obd.a_temp\":-40,\"obd.f_press\":48,\"obd.t_pos\":51.764706,\"obd.b_volt\":13.782000,\"obd.up_time\":2265,\"obd.m_dist\":4643,\"obd.m_time\":257,\"obd.d_dist\":200,\"obd.d_time\":771,\"obd.vin\":\"LFV3B28R8A3025310\",\"obd.f_rate\":10,\"obd.t_dist\":4843,\"obd.b_press\":101,\"obd.f_r_press\":48,\"obd.i_temp\":37,\"obd.i_press\":32,\"obd.r_torque\":4128,\"obd.a_torque\":2,\"obd.mf_mon\":1,\"obd.f_s_mon\":0,\"obd.c_c_mon\":0,\"obd.c_mon\":1,\"obd.e_s_mon\":1,\"obd.e_v_s_mon\":1,\"obd.o_s_mon\":1,\"obd.o_s_h_mon\":1}}xx")); + verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021111601/obd/info\",\"payload\":{\"obd.ts\":1637225390,\"obd.speed\":0,\"obd.f_lvl\":null,\"obd.odo\":0,\"obd.e_hours\":0,\"obd.ab_level\":null,\"obd.mil\":0,\"obd.dtcs\":null,\"obd.rpm\":0,\"obd.e_load\":null,\"obd.c_temp\":-40,\"obd.o_temp\":-273,\"obd.a_temp\":null,\"obd.f_press\":null,\"obd.t_pos\":0,\"obd.b_volt\":null,\"obd.up_time\":null,\"obd.m_dist\":null,\"obd.m_time\":null,\"obd.d_dist\":null,\"obd.d_time\":null,\"obd.vin\":\"NLVIN123456789ABC\",\"obd.brake\":0,\"obd.parking\":0,\"obd.s_w_angle\":null,\"obd.f_rate\":0,\"obd.f_econ\":0,\"obd.a_pos\":null,\"obd.t_dist\":0,\"obd.b_press\":null,\"obd.f_r_press\":null,\"obd.i_temp\":null,\"obd.i_press\":null,\"obd.r_torque\":null,\"obd.f_torque\":null,\"obd.max_avl_torque\":null,\"obd.a_torque\":-125,\"obd.d_e_f_vol\":null,\"obd.mf_mon\":null,\"obd.f_s_mon\":null,\"obd.c_c_mon\":null,\"obd.c_mon\":null,\"obd.h_c_mon\":null,\"obd.e_s_mon\":null,\"obd.s_a_s_mon\":null,\"obd.a_s_r_mon\":null,\"obd.e_g_s_mon\":null,\"obd.e_g_s_h_mon\":null,\"obd.e_v_s_mon\":null,\"obd.c_s_a_s_mon\":null,\"obd.b_p_c_s_mon\":null,\"obd.dpf_mon\":null,\"obd.n_c_mon\":null,\"obd.nmhc_mon\":null,\"obd.o_s_mon\":null,\"obd.o_s_h_mon\":null,\"obd.pf_mon\":null}}xx")); -- cgit v1.2.3 From ffd8ab43e4c2d7fa69753fe73d4e546896d920b6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Dec 2021 22:22:28 -0800 Subject: Fix status response --- src/main/java/org/traccar/protocol/TopinProtocolDecoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java index 40a583f2a..4fe261aa4 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -193,10 +193,12 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); + ByteBuf content = buf.retainedSlice(buf.readerIndex(), buf.readableBytes() - 2); + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); buf.readUnsignedByte(); // timezone - int interval = buf.readUnsignedByte(); + buf.readUnsignedByte(); // interval if (buf.readableBytes() >= 1 + 2) { position.set(Position.KEY_RSSI, buf.readUnsignedByte()); } @@ -210,8 +212,6 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_HEART_RATE, buf.readUnsignedByte()); } - ByteBuf content = Unpooled.buffer(); - content.writeByte(interval); sendResponse(channel, length, type, content); return position; -- cgit v1.2.3 From f910e56a45a4adc08287b6674d011bd25ea52b27 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 12 Dec 2021 10:54:18 -0800 Subject: Token to override current session --- .../org/traccar/api/resource/SessionResource.java | 33 +++++++++++++--------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index e3c5d457f..60ce5490a 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,8 +57,19 @@ public class SessionResource extends BaseResource { @PermitAll @GET public User get(@QueryParam("token") String token) throws SQLException, UnsupportedEncodingException { + + if (token != null) { + User user = Context.getUsersManager().getUserByToken(token); + if (user != null) { + Context.getPermissionsManager().checkUserEnabled(user.getId()); + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + return user; + } + } + Long userId = (Long) request.getSession().getAttribute(USER_ID_KEY); if (userId == null) { + Cookie[] cookies = request.getCookies(); String email = null, password = null; if (cookies != null) { @@ -77,24 +88,20 @@ public class SessionResource extends BaseResource { if (email != null && password != null) { User user = Context.getPermissionsManager().login(email, password); if (user != null) { - userId = user.getId(); - request.getSession().setAttribute(USER_ID_KEY, userId); - } - } else if (token != null) { - User user = Context.getUsersManager().getUserByToken(token); - if (user != null) { - userId = user.getId(); - request.getSession().setAttribute(USER_ID_KEY, userId); + Context.getPermissionsManager().checkUserEnabled(user.getId()); + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + return user; } } - } - if (userId != null) { + } else { + Context.getPermissionsManager().checkUserEnabled(userId); return Context.getPermissionsManager().getUser(userId); - } else { - throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); + } + + throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } @PermitAll -- cgit v1.2.3 From 5a2baafba92958c82b81873dae19c5df7e793eea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Dec 2021 22:19:47 -0800 Subject: Handle missing parameters --- .../traccar/protocol/DmtHttpProtocolDecoder.java | 30 ++++++++++++---------- .../protocol/DmtHttpProtocolDecoderTest.java | 3 +++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index 15cf84a5f..815cce987 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -174,21 +174,25 @@ public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { position.set(Position.KEY_INDEX, root.getInt("sqn")); position.set(Position.KEY_EVENT, root.getInt("reason")); - JsonArray analogues = root.getJsonArray("analogues"); - for (int i = 0; i < analogues.size(); i++) { - JsonObject adc = analogues.getJsonObject(i); - position.set(Position.PREFIX_ADC + adc.getInt("id"), adc.getInt("val")); + if (root.containsKey("analogues")) { + JsonArray analogues = root.getJsonArray("analogues"); + for (int i = 0; i < analogues.size(); i++) { + JsonObject adc = analogues.getJsonObject(i); + position.set(Position.PREFIX_ADC + adc.getInt("id"), adc.getInt("val")); + } } - int input = root.getInt("inputs"); - int output = root.getInt("outputs"); - int status = root.getInt("status"); - - position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); - - position.set(Position.KEY_INPUT, input); - position.set(Position.KEY_OUTPUT, output); - position.set(Position.KEY_STATUS, status); + if (root.containsKey("inputs")) { + int input = root.getInt("inputs"); + position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); + position.set(Position.KEY_INPUT, input); + } + if (root.containsKey("outputs")) { + position.set(Position.KEY_OUTPUT, root.getInt("outputs")); + } + if (root.containsKey("status")) { + position.set(Position.KEY_STATUS, root.getInt("status")); + } if (root.containsKey("counters")) { JsonArray counters = root.getJsonArray("counters"); diff --git a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java index bed56ba30..31d0efa12 100644 --- a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class DmtHttpProtocolDecoderTest extends ProtocolTest { var decoder = new DmtHttpProtocolDecoder(null); + verifyAttributes(decoder, request(HttpMethod.POST, "/", + buffer("{\"date\":\"2021-12-12T16:04:52Z\",\"device\":{\"sn\":\"416581\",\"prod\":85,\"rev\":1,\"fw\":\"1.12\",\"iccid\":\"89011702278612797427\",\"imei\":\"351358810439486\"},\"sqn\":1549,\"reason\":42,\"counters\":[{\"id\":0,\"val\":5304},{\"id\":3,\"val\":3200},{\"id\":4,\"val\":5066},{\"id\":128,\"val\":1},{\"id\":129,\"val\":8},{\"id\":130,\"val\":0},{\"id\":131,\"val\":0},{\"id\":132,\"val\":0},{\"id\":134,\"val\":1},{\"id\":138,\"val\":0},{\"id\":139,\"val\":36},{\"id\":142,\"val\":1629023},{\"id\":145,\"val\":0},{\"id\":146,\"val\":1}]}"))); + verifyAttributes(decoder, request(HttpMethod.POST, "/", buffer("{\"date\":\"2021-10-04T18:15:47Z\",\"device\":{\"sn\":\"403809\",\"prod\":85,\"rev\":1,\"fw\":\"1.12\",\"iccid\":\"89011702278483601922\",\"imei\":\"352656106127312\"},\"sqn\":40927,\"reason\":11,\"analogues\":[{\"id\":1,\"val\":4265},{\"id\":3,\"val\":3800},{\"id\":4,\"val\":12},{\"id\":5,\"val\":4251}],\"inputs\":1,\"outputs\":0,\"status\":137}"))); -- cgit v1.2.3 From 54de76fe8645c8da30bbc08d1c8efb1ad472e8b5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Dec 2021 22:51:21 -0800 Subject: Fix time decoding --- src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java index 5db7f0bc0..65333ba6e 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java @@ -52,7 +52,7 @@ public class HoopoProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - Date time = new Date(OffsetDateTime.parse(eventData.getString("receiveTime")).toInstant().toEpochMilli()); + Date time = new Date(OffsetDateTime.parse(json.getString("eventTime")).toInstant().toEpochMilli()); position.setTime(time); position.setValid(true); -- cgit v1.2.3 From eda05aa8e846b273c4cb30f77ebf3c4db48443ad Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Dec 2021 22:58:13 -0800 Subject: Decode battery from heartbeat --- .../org/traccar/protocol/MiniFinderProtocolDecoder.java | 17 +++++++++++++++-- .../traccar/protocol/MiniFinderProtocolDecoderTest.java | 7 ++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java index 2b7a960c4..d5be31cec 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2021 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,7 +143,7 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { } DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null || !sentence.matches("![3A-D],.*")) { + if (deviceSession == null || !sentence.matches("![35A-D],.*")) { return null; } @@ -161,6 +161,19 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type.equals("5")) { + + String[] values = sentence.split(","); + + getLastLocation(position, null); + + position.set(Position.KEY_RSSI, Integer.parseInt(values[1])); + if (values.length >= 4) { + position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[3])); + } + + return position; + } else if (type.equals("B") || type.equals("D")) { Parser parser = new Parser(PATTERN_BD, sentence); diff --git a/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java index 2d7e4e597..1a9756226 100644 --- a/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class MiniFinderProtocolDecoderTest extends ProtocolTest { @@ -19,7 +20,11 @@ public class MiniFinderProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "!1,123456789012345")); - verifyNull(decoder, text( + verifyAttribute(decoder, text( + "!5,17,V,50"), + Position.KEY_BATTERY_LEVEL, 50); + + verifyAttributes(decoder, text( "!5,17,V")); verifyNull(decoder, text( -- cgit v1.2.3 From 9403fd618339d0ba432794a162f90f22cdc2ebd4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Dec 2021 19:32:38 -0800 Subject: Implement protocol response --- .../org/traccar/protocol/TzoneProtocolDecoder.java | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 249915b39..9e04f0b02 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -19,8 +19,11 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; 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.config.Keys; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; @@ -30,6 +33,10 @@ import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; public class TzoneProtocolDecoder extends BaseProtocolDecoder { @@ -37,6 +44,18 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + private void sendResponse(Channel channel, SocketAddress remoteAddress, int index) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + String ack = String.format("@ACK,%d#", index); + String time = String.format("@UTC time:%s", dateFormat.format(new Date())); + + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(ack + time, remoteAddress)); + } + } + private String decodeAlarm(Short value) { switch (value) { case 0x01: @@ -348,6 +367,10 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } + if (Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + sendResponse(channel, remoteAddress, buf.getUnsignedShort(buf.writerIndex() - 6)); + } + return position; } -- cgit v1.2.3 From ddd9a01c6e88e654f3fd377adcee36947e4e1e9d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Dec 2021 20:48:39 -0800 Subject: Decode ignition --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 5eab10498..0eb6f8776 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -23,6 +23,7 @@ import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; +import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -190,8 +191,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid, rssi))); } - position.set(Position.KEY_INPUT, parser.nextHexInt()); - position.set(Position.KEY_OUTPUT, parser.nextHexInt()); + int input = parser.nextHexInt(); + int output = parser.nextHexInt(); + + position.set(Position.KEY_IGNITION, BitUtil.check(input, 2)); + + position.set(Position.KEY_INPUT, input); + position.set(Position.KEY_OUTPUT, output); if (parser.hasNext(2)) { -- cgit v1.2.3 From fefa27140fcd7dca13a45f4186797420cb41604c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Dec 2021 22:31:18 -0800 Subject: Alternative location format --- .../org/traccar/protocol/FlexApiProtocolDecoder.java | 18 +++++++++++++++--- .../traccar/protocol/FlexApiProtocolDecoderTest.java | 6 ++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index 25a8f7090..167896386 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -55,9 +55,17 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { if (topic.contains("gnss")) { position.setValid(true); - position.setTime(new Date(payload.getInt("time") * 1000L)); - position.setLatitude(payload.getJsonNumber("lat").doubleValue()); - position.setLongitude(payload.getJsonNumber("log").doubleValue()); + + if (payload.containsKey("time")) { + position.setTime(new Date(payload.getInt("time") * 1000L)); + position.setLatitude(payload.getJsonNumber("lat").doubleValue()); + position.setLongitude(payload.getJsonNumber("log").doubleValue()); + } else { + position.setTime(new Date(payload.getInt("gnss.ts") * 1000L)); + position.setLatitude(payload.getJsonNumber("gnss.latitude").doubleValue()); + position.setLongitude(payload.getJsonNumber("gnss.longitude").doubleValue()); + } + position.setAltitude(payload.getJsonNumber("gnss.altitude").doubleValue()); position.setSpeed(payload.getJsonNumber("gnss.speed").doubleValue()); position.setCourse(payload.getJsonNumber("gnss.heading").doubleValue()); @@ -81,6 +89,10 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_VIN, payload.getString("obd.vin")); } + } else if (topic.contains("cellular1")) { + + getLastLocation(position, new Date(payload.getInt("modem1.ts") * 1000L)); + } else { return null; diff --git a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java index 83f36f394..a276a01e9 100644 --- a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class FlexApiProtocolDecoderTest extends ProtocolTest { var decoder = new FlexApiProtocolDecoder(null); + verifyAttributes(decoder, text( + "${\"topic\":\"v1/VF3102021113001/gnss/info\",\"payload\":{\"gnss.ts\":1639713510,\"gnss.latitude\":30.587509,\"gnss.longitude\":104.053650,\"gnss.altitude\":391,\"gnss.speed\":0,\"gnss.heading\":0,\"gnss.hdop\":1.100000,\"gnss.fix\":4,\"gnss.num_sv\":10}}xx")); + + verifyNull(decoder, text( + "${\"topic\":\"v1/VF3102021113001/cellular1/info\",\"payload\":{\"modem1.ts\":1639713510,\"modem1.imei\":\"863674047326655\",\"modem1.imsi\":\"\",\"modem1.iccid\":\"\",\"modem1.phone_num\":\"\",\"modem1.signal_lvl\":0,\"modem1.reg_status\":0,\"modem1.operator\":\"\",\"modem1.network\":0,\"modem1.lac\":\"\",\"modem1.cell_id\":\"\",\"modem1.rssi\":0,\"modem1.rsrp\":0,\"modem1.rsrq\":0,\"cellular1.status\":2,\"cellular1.ip\":\"0.0.0.0\",\"cellular1.netmask\":\"255.255.255.255\",\"cellular1.gateway\":\"0.0.0.0\",\"cellular1.dns1\":\"0.0.0.0\",\"cellular1.up_at\":602}}xx")); + verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102029000003/obd/info\",\"payload\":{\"obd.ts\":1639037377,\"obd.speed\":211,\"obd.f_lvl\":50.196079,\"obd.mil\":0,\"obd.dtcs\":0,\"obd.rpm\":14531.250000,\"obd.e_load\":50.980392,\"obd.c_temp\":118,\"obd.o_temp\":56,\"obd.a_temp\":-40,\"obd.f_press\":48,\"obd.t_pos\":51.764706,\"obd.b_volt\":13.782000,\"obd.up_time\":2265,\"obd.m_dist\":4643,\"obd.m_time\":257,\"obd.d_dist\":200,\"obd.d_time\":771,\"obd.vin\":\"LFV3B28R8A3025310\",\"obd.f_rate\":10,\"obd.t_dist\":4843,\"obd.b_press\":101,\"obd.f_r_press\":48,\"obd.i_temp\":37,\"obd.i_press\":32,\"obd.r_torque\":4128,\"obd.a_torque\":2,\"obd.mf_mon\":1,\"obd.f_s_mon\":0,\"obd.c_c_mon\":0,\"obd.c_mon\":1,\"obd.e_s_mon\":1,\"obd.e_v_s_mon\":1,\"obd.o_s_mon\":1,\"obd.o_s_h_mon\":1}}xx")); -- cgit v1.2.3 From 80defa745c10ba5a43fbc0b05f66b5567d782348 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Dec 2021 22:34:35 -0800 Subject: Remove unused code --- src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index 167896386..d4d539a9e 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -89,10 +89,6 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_VIN, payload.getString("obd.vin")); } - } else if (topic.contains("cellular1")) { - - getLastLocation(position, new Date(payload.getInt("modem1.ts") * 1000L)); - } else { return null; -- cgit v1.2.3 From 25dfb6a1fb66f5565ec338928d000d271f7e62db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 21 Dec 2021 23:26:13 -0800 Subject: Encode response message --- src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 9e04f0b02..819c42471 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -17,6 +17,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 org.traccar.BaseProtocolDecoder; import org.traccar.Context; @@ -33,6 +34,7 @@ import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; @@ -51,8 +53,10 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { String ack = String.format("@ACK,%d#", index); String time = String.format("@UTC time:%s", dateFormat.format(new Date())); + ByteBuf response = Unpooled.copiedBuffer(ack + time, StandardCharsets.US_ASCII); + if (channel != null) { - channel.writeAndFlush(new NetworkMessage(ack + time, remoteAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } -- cgit v1.2.3 From 19f170b8c147935c8df4044a4fa3b6456baad6c7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Dec 2021 23:00:47 -0800 Subject: Add Digital Systems DSF22 protocol --- setup/default.xml | 1 + .../org/traccar/protocol/Dsf22FrameDecoder.java | 44 +++++++++++ .../java/org/traccar/protocol/Dsf22Protocol.java | 40 ++++++++++ .../org/traccar/protocol/Dsf22ProtocolDecoder.java | 90 ++++++++++++++++++++++ .../traccar/protocol/Dsf22FrameDecoderTest.java | 23 ++++++ .../traccar/protocol/Dsf22ProtocolDecoderTest.java | 23 ++++++ 6 files changed, 221 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java create mode 100644 src/main/java/org/traccar/protocol/Dsf22Protocol.java create mode 100644 src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java create mode 100644 src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 83788b19b..6c0eef111 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -303,5 +303,6 @@ 5233 5234 5235 + 5236 diff --git a/src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java b/src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java new file mode 100644 index 000000000..388c97f85 --- /dev/null +++ b/src/main/java/org/traccar/protocol/Dsf22FrameDecoder.java @@ -0,0 +1,44 @@ +/* + * Copyright 2021 Anton Tananaev (anton@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 Dsf22FrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + if (buf.readableBytes() < 21) { + return null; + } + + int count = buf.getUnsignedByte(buf.readerIndex() + 4); + + int length = 2 + 2 + 1 + count * (4 + 4 + 4 + 1 + 2 + 1); + + if (buf.readableBytes() >= length) { + return buf.readRetainedSlice(length); + } else { + return null; + } + } + +} diff --git a/src/main/java/org/traccar/protocol/Dsf22Protocol.java b/src/main/java/org/traccar/protocol/Dsf22Protocol.java new file mode 100644 index 000000000..bffc3e419 --- /dev/null +++ b/src/main/java/org/traccar/protocol/Dsf22Protocol.java @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Anton Tananaev (anton@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 Dsf22Protocol extends BaseProtocol { + + public Dsf22Protocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new Dsf22FrameDecoder()); + pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); + } + }); + addServer(new TrackerServer(true, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java new file mode 100644 index 000000000..d5a9df7bc --- /dev/null +++ b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java @@ -0,0 +1,90 @@ +/* + * Copyright 2021 Anton Tananaev (anton@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.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +public class Dsf22ProtocolDecoder extends BaseProtocolDecoder { + + public Dsf22ProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + buf.skipBytes(2); // header + + String id = ByteBufUtil.hexDump(buf.readSlice(2)); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); + if (deviceSession == null) { + return null; + } + + List positions = new LinkedList<>(); + int count = buf.readUnsignedByte(); + + for (int i = 0; i < count; i++) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setLatitude(buf.readInt()); + position.setLongitude(buf.readInt()); + position.setTime(new Date(946684800000L + buf.readUnsignedInt())); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.001); + + int status = buf.readUnsignedByte(); + position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); + position.set(Position.PREFIX_IN + 1, BitUtil.check(status, 1)); + position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 4)); + position.set(Position.KEY_ALARM, BitUtil.check(status, 6) ? Position.ALARM_JAMMING : null); + position.set(Position.KEY_STATUS, status); + + positions.add(position); + + } + + if (channel != null) { + byte[] response = {0x01}; + channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(response), remoteAddress)); + } + + return positions; + } + +} diff --git a/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java new file mode 100644 index 000000000..fc18b0560 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java @@ -0,0 +1,23 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Dsf22FrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new Dsf22FrameDecoder(); + + verifyFrame( + binary("4642000101A8EE5F0ECA5FF421B33F524E32610401"), + decoder.decode(null, null, binary("4642000101A8EE5F0ECA5FF421B33F524E32610401"))); + + verifyFrame( + binary("4642000103A8EE5F0ECA5FF421B33F524E326104010216600EFC92F421B63F524E366104013238600E1EBEF421B93F524E35610401"), + decoder.decode(null, null, binary("4642000103A8EE5F0ECA5FF421B33F524E326104010216600EFC92F421B63F524E366104013238600E1EBEF421B93F524E35610401"))); + + } + +} diff --git a/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java new file mode 100644 index 000000000..96cd78f03 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java @@ -0,0 +1,23 @@ +package org.traccar.protocol; + +import org.junit.Ignore; +import org.junit.Test; +import org.traccar.ProtocolTest; + +@Ignore +public class Dsf22ProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new Dsf22ProtocolDecoder(null); + + verifyPositions(decoder, binary( + "4642000101A8EE5F0ECA5FF421B33F524E32610401")); + + verifyPositions(decoder, binary( + "4642000103A8EE5F0ECA5FF421B33F524E326104010216600EFC92F421B63F524E366104013238600E1EBEF421B93F524E35610401")); + + } + +} -- cgit v1.2.3 From 29c63d9bf48623ef11e89399e4c7c0e09bf1c446 Mon Sep 17 00:00:00 2001 From: soshial Date: Mon, 27 Dec 2021 15:38:46 +0400 Subject: revert to the original filtering logic --- src/main/java/org/traccar/handler/FilterHandler.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 6331ff773..e8cafabc8 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -147,12 +147,9 @@ public class FilterHandler extends BaseDataHandler { private boolean filter(Position position) { - if (skipAttributes(position)) { - return false; - } - StringBuilder filterType = new StringBuilder(); + // filter out invalid data if (filterInvalid(position)) { filterType.append("Invalid "); } @@ -168,10 +165,8 @@ public class FilterHandler extends BaseDataHandler { if (filterApproximate(position)) { filterType.append("Approximate "); } - if (filterStatic(position)) { - filterType.append("Static "); - } + // filter out excessive data long deviceId = position.getDeviceId(); if (filterDuplicate || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { Position preceding = null; @@ -186,13 +181,13 @@ public class FilterHandler extends BaseDataHandler { } else { preceding = getLastReceivedPosition(deviceId); } - if (skipLimit(position, preceding)) { - return false; - } if (filterDuplicate(position, preceding)) { filterType.append("Duplicate "); } - if (filterDistance(position, preceding)) { + if (filterStatic(position) && !skipLimit(position, preceding) && !skipAttributes(position)) { + filterType.append("Static "); + } + if (filterDistance(position, preceding) && !skipLimit(position, preceding) && !skipAttributes(position)) { filterType.append("Distance "); } if (filterMaxSpeed(position, preceding)) { -- cgit v1.2.3 From 41453ca2ee76372a031ea206c264c1c7cde58ee6 Mon Sep 17 00:00:00 2001 From: soshial Date: Mon, 27 Dec 2021 22:16:08 +0400 Subject: filtering logic: fix static --- src/main/java/org/traccar/handler/FilterHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index e8cafabc8..049512765 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -168,7 +168,7 @@ public class FilterHandler extends BaseDataHandler { // filter out excessive data long deviceId = position.getDeviceId(); - if (filterDuplicate || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { + if (filterDuplicate || filterStatic || filterDistance > 0 || filterMaxSpeed > 0 || filterMinPeriod > 0) { Position preceding = null; if (filterRelative) { try { -- cgit v1.2.3 From 407147946a7c1a49242a78227351605c2ece9e32 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Dec 2021 20:47:41 -0800 Subject: Decode additional attributes --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 11 +++++++++++ .../org/traccar/protocol/MeitrackProtocolDecoderTest.java | 3 +++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 0eb6f8776..4a1324840 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -424,6 +424,14 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case 0x07: position.set(Position.KEY_RSSI, buf.readUnsignedByte()); break; + case 0x14: + position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); + break; + case 0x15: + int input = buf.readUnsignedByte(); + position.set(Position.KEY_IGNITION, BitUtil.check(input, 2)); + position.set(Position.KEY_INPUT, input); + break; case 0x97: position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); break; @@ -452,6 +460,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case 0x0B: position.setAltitude(buf.readShortLE()); break; + case 0x16: + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE() * 0.01); + break; case 0x19: position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); break; diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 58861c139..1c90468bd 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = new MeitrackProtocolDecoder(null); + verifyPositions(decoder, binary( + "2424423233392c3836323039303035303030373436352c4343452c0100000003004300130006050006000700140015801b00080800000900000a00000b0000165105198d011a630540160005024c5e910103590bfe0204922153290c6b2501000dd5b50200004300130006050006000700140015011b00080800000900000a00000b0000165005198d011a630540010005024c5e910103590bfe0204932153290c6b2501000dd6b50200004300130006050006000700140015011b00080800000900000a00000b0000165205198d011a630540230005024c5e910103590bfe0204942153290c6b2501000dd7b50200002a43330d0a")); + verifyPosition(decoder, buffer( "$$D149,867047043162018,AAA,35,-1.264865,36.800705,211001105240,A,9,20,41.0,323,1,1697,1,0,000|00||,0000,4.33|12.96|1.92|2.72|2.69,0.000000|0|0.000000,*E1")); -- cgit v1.2.3 From ea5d34b5102e75557668f85c6f3124ea5417a219 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Dec 2021 20:55:49 -0800 Subject: Fix protocol response --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index bdcc12c4c..8314442a3 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -235,12 +235,11 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { positions.add(position); } - int checksum = buf.readUnsignedByte(); if (channel != null) { ByteBuf response = Unpooled.buffer(); response.writeCharSequence(type, StandardCharsets.US_ASCII); response.writeByte(count); - response.writeByte(checksum); + response.writeByte(Checksum.xor(response.nioBuffer())); channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } -- cgit v1.2.3 From 6236628bbd0260399b83dc077388f881311e4bc3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Dec 2021 09:05:58 -0800 Subject: Remove incorrect ignition --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 4a1324840..8cdc30935 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -191,13 +191,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid, rssi))); } - int input = parser.nextHexInt(); - int output = parser.nextHexInt(); - - position.set(Position.KEY_IGNITION, BitUtil.check(input, 2)); - - position.set(Position.KEY_INPUT, input); - position.set(Position.KEY_OUTPUT, output); + position.set(Position.KEY_INPUT, parser.nextHexInt()); + position.set(Position.KEY_OUTPUT, parser.nextHexInt()); if (parser.hasNext(2)) { @@ -428,9 +423,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); break; case 0x15: - int input = buf.readUnsignedByte(); - position.set(Position.KEY_IGNITION, BitUtil.check(input, 2)); - position.set(Position.KEY_INPUT, input); + position.set(Position.KEY_INPUT, buf.readUnsignedByte()); break; case 0x97: position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); -- cgit v1.2.3 From fe25a2a89533fa39a3df7a4b248dbf25b3a4e845 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Dec 2021 09:08:41 -0800 Subject: Remove unused import --- src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 8cdc30935..a9cc1de3a 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -23,7 +23,6 @@ import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; -import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; -- cgit v1.2.3 From 019dfdd9d635556576c1070b413e69d7018eb3b3 Mon Sep 17 00:00:00 2001 From: Sun Howwrongbum Date: Fri, 31 Dec 2021 08:16:39 +0530 Subject: docs: add script to generate config snippets --- tools/gen-config-doc.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tools/gen-config-doc.py diff --git a/tools/gen-config-doc.py b/tools/gen-config-doc.py new file mode 100644 index 000000000..a0f3014b0 --- /dev/null +++ b/tools/gen-config-doc.py @@ -0,0 +1,47 @@ +#!/usr/bin/python + +import re + + +def get_config_key_descriptions(): + desc_re = re.compile(r"(/\*\*\n|\s+\*/|\s+\*)") + key_match_re = re.compile(r"\(\n(.+)\);", re.DOTALL) + key_split_re = re.compile(r",\s+", re.DOTALL) + snippets = [] + + with open("../src/main/java/org/traccar/config/Keys.java", "r") as f: + code = f.read() + config = re.findall( + r"(/\*\*.*?\*/)\n\s+(public static final Config.*?;)", code, re.DOTALL + ) + for i in config: + try: + key_match = key_match_re.search(i[1]) + if key_match: + description = desc_re.sub("", i[0]).strip() + terms = [x.strip() for x in key_split_re.split(key_match.group(1))] + key = terms[0].replace('"', "") + default = terms[2] if len(terms) == 3 else None + snippets.append( + f"""
+
+
+ {key} config +
+

+ {description}{f" Default: {default}" if default else ""} +

+
+
""" + ) + except IndexError: + # will continue if key_match.group(1) or terms[0] does not exist + # for some reason + pass + + return ("\n").join(snippets) + + +if __name__ == "__main__": + html = get_config_key_descriptions() + print(html) -- cgit v1.2.3 From b06ab631df79ebcace59478b44108e155ad802a6 Mon Sep 17 00:00:00 2001 From: Sun Howwrongbum Date: Fri, 31 Dec 2021 14:01:41 +0530 Subject: fix: add period to config default text Co-authored-by: Anton Tananaev --- tools/gen-config-doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gen-config-doc.py b/tools/gen-config-doc.py index a0f3014b0..c6d133ca6 100644 --- a/tools/gen-config-doc.py +++ b/tools/gen-config-doc.py @@ -29,7 +29,7 @@ def get_config_key_descriptions(): {key} config

- {description}{f" Default: {default}" if default else ""} + {description}{f" Default: {default}." if default else ""}

""" -- cgit v1.2.3 From b25eb46b1b5a2e1633f994f3478d237a190f9f02 Mon Sep 17 00:00:00 2001 From: Sun Howwrongbum Date: Fri, 31 Dec 2021 16:48:58 +0530 Subject: docs: add line breaks in config descriptions --- tools/gen-config-doc.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/gen-config-doc.py b/tools/gen-config-doc.py index c6d133ca6..62c4c535e 100644 --- a/tools/gen-config-doc.py +++ b/tools/gen-config-doc.py @@ -18,7 +18,12 @@ def get_config_key_descriptions(): try: key_match = key_match_re.search(i[1]) if key_match: - description = desc_re.sub("", i[0]).strip() + description = "
".join( + [ + x.strip().replace("\n", "") + for x in desc_re.sub("\n", i[0]).strip().split("\n\n") + ] + ) terms = [x.strip() for x in key_split_re.split(key_match.group(1))] key = terms[0].replace('"', "") default = terms[2] if len(terms) == 3 else None @@ -29,7 +34,7 @@ def get_config_key_descriptions(): {key} config

- {description}{f" Default: {default}." if default else ""} + {description}{f"
Default: {default}." if default else ""}

""" -- cgit v1.2.3 From 9e3e63d00857fa297b4e882bdcf6ee06f27c6054 Mon Sep 17 00:00:00 2001 From: Sun Howwrongbum Date: Fri, 31 Dec 2021 16:50:32 +0530 Subject: docs: fix config file path --- tools/gen-config-doc.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/gen-config-doc.py b/tools/gen-config-doc.py index 62c4c535e..e309da942 100644 --- a/tools/gen-config-doc.py +++ b/tools/gen-config-doc.py @@ -1,15 +1,20 @@ #!/usr/bin/python import re +import os +_KEYS_FILE = os.path.join( + os.path.dirname(__file__), "../src/main/java/org/traccar/config/Keys.java" +) + def get_config_key_descriptions(): desc_re = re.compile(r"(/\*\*\n|\s+\*/|\s+\*)") key_match_re = re.compile(r"\(\n(.+)\);", re.DOTALL) key_split_re = re.compile(r",\s+", re.DOTALL) snippets = [] - with open("../src/main/java/org/traccar/config/Keys.java", "r") as f: + with open(_KEYS_FILE, "r") as f: code = f.read() config = re.findall( r"(/\*\*.*?\*/)\n\s+(public static final Config.*?;)", code, re.DOTALL -- cgit v1.2.3 From ac64dba0a21b50aa2090f2ff7f20bc64f7b8256f Mon Sep 17 00:00:00 2001 From: Sun Howwrongbum Date: Fri, 31 Dec 2021 16:54:40 +0530 Subject: docs: rename script to be importable --- tools/gen-config-doc.py | 57 ------------------------------------------------- tools/gen_config_doc.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 57 deletions(-) delete mode 100644 tools/gen-config-doc.py create mode 100644 tools/gen_config_doc.py diff --git a/tools/gen-config-doc.py b/tools/gen-config-doc.py deleted file mode 100644 index e309da942..000000000 --- a/tools/gen-config-doc.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/python - -import re -import os - - -_KEYS_FILE = os.path.join( - os.path.dirname(__file__), "../src/main/java/org/traccar/config/Keys.java" -) - -def get_config_key_descriptions(): - desc_re = re.compile(r"(/\*\*\n|\s+\*/|\s+\*)") - key_match_re = re.compile(r"\(\n(.+)\);", re.DOTALL) - key_split_re = re.compile(r",\s+", re.DOTALL) - snippets = [] - - with open(_KEYS_FILE, "r") as f: - code = f.read() - config = re.findall( - r"(/\*\*.*?\*/)\n\s+(public static final Config.*?;)", code, re.DOTALL - ) - for i in config: - try: - key_match = key_match_re.search(i[1]) - if key_match: - description = "
".join( - [ - x.strip().replace("\n", "") - for x in desc_re.sub("\n", i[0]).strip().split("\n\n") - ] - ) - terms = [x.strip() for x in key_split_re.split(key_match.group(1))] - key = terms[0].replace('"', "") - default = terms[2] if len(terms) == 3 else None - snippets.append( - f"""
-
-
- {key} config -
-

- {description}{f"
Default: {default}." if default else ""} -

-
-
""" - ) - except IndexError: - # will continue if key_match.group(1) or terms[0] does not exist - # for some reason - pass - - return ("\n").join(snippets) - - -if __name__ == "__main__": - html = get_config_key_descriptions() - print(html) diff --git a/tools/gen_config_doc.py b/tools/gen_config_doc.py new file mode 100644 index 000000000..e309da942 --- /dev/null +++ b/tools/gen_config_doc.py @@ -0,0 +1,57 @@ +#!/usr/bin/python + +import re +import os + + +_KEYS_FILE = os.path.join( + os.path.dirname(__file__), "../src/main/java/org/traccar/config/Keys.java" +) + +def get_config_key_descriptions(): + desc_re = re.compile(r"(/\*\*\n|\s+\*/|\s+\*)") + key_match_re = re.compile(r"\(\n(.+)\);", re.DOTALL) + key_split_re = re.compile(r",\s+", re.DOTALL) + snippets = [] + + with open(_KEYS_FILE, "r") as f: + code = f.read() + config = re.findall( + r"(/\*\*.*?\*/)\n\s+(public static final Config.*?;)", code, re.DOTALL + ) + for i in config: + try: + key_match = key_match_re.search(i[1]) + if key_match: + description = "
".join( + [ + x.strip().replace("\n", "") + for x in desc_re.sub("\n", i[0]).strip().split("\n\n") + ] + ) + terms = [x.strip() for x in key_split_re.split(key_match.group(1))] + key = terms[0].replace('"', "") + default = terms[2] if len(terms) == 3 else None + snippets.append( + f"""
+
+
+ {key} config +
+

+ {description}{f"
Default: {default}." if default else ""} +

+
+
""" + ) + except IndexError: + # will continue if key_match.group(1) or terms[0] does not exist + # for some reason + pass + + return ("\n").join(snippets) + + +if __name__ == "__main__": + html = get_config_key_descriptions() + print(html) -- cgit v1.2.3 From 1eb5988991f98ecbcef33f53713e2cd452cc2014 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Fri, 31 Dec 2021 17:41:03 +0100 Subject: feat: Totem - add some basic commands --- src/main/java/org/traccar/protocol/TotemProtocol.java | 5 +++++ src/main/java/org/traccar/protocol/TotemProtocolEncoder.java | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java index f8cda8358..7cf30475b 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocol.java +++ b/src/main/java/org/traccar/protocol/TotemProtocol.java @@ -26,6 +26,11 @@ public class TotemProtocol extends BaseProtocol { public TotemProtocol() { setSupportedDataCommands( + Command.TYPE_CUSTOM, + Command.TYPE_REBOOT_DEVICE, + Command.TYPE_FACTORY_RESET, + Command.TYPE_GET_VERSION, + Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_RESUME, Command.TYPE_ENGINE_STOP ); diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java index a96dd1ee3..4717c3920 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java @@ -32,6 +32,16 @@ public class TotemProtocolEncoder extends StringProtocolEncoder { initDevicePassword(command, "000000"); switch (command.getType()) { + case Command.TYPE_CUSTOM: + return formatCommand(command, "*%s,%s#", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); + case Command.TYPE_REBOOT_DEVICE: + return formatCommand(command, "*%s,006#", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_FACTORY_RESET: + return formatCommand(command, "*%s,007#", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_GET_VERSION: + return formatCommand(command, "*%s,056#", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_POSITION_SINGLE: + return formatCommand(command, "*%s,012#", Command.KEY_DEVICE_PASSWORD); // Assuming PIN 8 (Output C) is the power wire, like manual says but it can be PIN 5,7,8 case Command.TYPE_ENGINE_STOP: return formatCommand(command, "*%s,025,C,1#", Command.KEY_DEVICE_PASSWORD); -- cgit v1.2.3 From a30e419820ce40f209c674650477bae1947d85ec Mon Sep 17 00:00:00 2001 From: Sun Howwrongbum Date: Sat, 1 Jan 2022 16:32:25 +0530 Subject: docs: refactor config keys generation --- tools/gen_config_doc.py | 66 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/tools/gen_config_doc.py b/tools/gen_config_doc.py index e309da942..caedba577 100644 --- a/tools/gen_config_doc.py +++ b/tools/gen_config_doc.py @@ -8,50 +8,70 @@ _KEYS_FILE = os.path.join( os.path.dirname(__file__), "../src/main/java/org/traccar/config/Keys.java" ) -def get_config_key_descriptions(): + +def get_config_keys(): + """Parses Keys.java to extract keys to be used in configuration files + + Args: None + + Returns: + list: A list of dict containing the following keys - + 'key': A dot separated name of the config key + 'description': A list of str + """ desc_re = re.compile(r"(/\*\*\n|\s+\*/|\s+\*)") key_match_re = re.compile(r"\(\n(.+)\);", re.DOTALL) key_split_re = re.compile(r",\s+", re.DOTALL) - snippets = [] + keys = [] with open(_KEYS_FILE, "r") as f: - code = f.read() config = re.findall( - r"(/\*\*.*?\*/)\n\s+(public static final Config.*?;)", code, re.DOTALL + r"(/\*\*.*?\*/)\n\s+(public static final Config.*?;)", f.read(), re.DOTALL ) for i in config: try: key_match = key_match_re.search(i[1]) if key_match: - description = "
".join( - [ - x.strip().replace("\n", "") - for x in desc_re.sub("\n", i[0]).strip().split("\n\n") - ] - ) terms = [x.strip() for x in key_split_re.split(key_match.group(1))] key = terms[0].replace('"', "") - default = terms[2] if len(terms) == 3 else None - snippets.append( - f"""
+ description = [ + x.strip().replace("\n", "") + for x in desc_re.sub("\n", i[0]).strip().split("\n\n") + ] + if len(terms) == 3: + description.append(f"Default: {terms[2]}") + keys.append( + { + "key": key, + "description": description, + } + ) + except IndexError: + # will continue if key_match.group(1) or terms[0] does not exist + # for some reason + pass + + return keys + + +def get_html(): + return ("\n").join( + [ + f"""
- {key} config + {x["key"]} config

- {description}{f"
Default: {default}." if default else ""} + {"
".join(x["description"])}

""" - ) - except IndexError: - # will continue if key_match.group(1) or terms[0] does not exist - # for some reason - pass - - return ("\n").join(snippets) + for x in get_config_keys() + ] + ) if __name__ == "__main__": - html = get_config_key_descriptions() + html = get_html() print(html) -- cgit v1.2.3 From 3690950850c388373870dd973ec12e1b8412ec0f Mon Sep 17 00:00:00 2001 From: Sun Howwrongbum Date: Sat, 1 Jan 2022 16:32:41 +0530 Subject: feat: generate config keys as pug --- tools/gen_config_doc.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/tools/gen_config_doc.py b/tools/gen_config_doc.py index caedba577..98266386e 100644 --- a/tools/gen_config_doc.py +++ b/tools/gen_config_doc.py @@ -2,7 +2,7 @@ import re import os - +import argparse _KEYS_FILE = os.path.join( os.path.dirname(__file__), "../src/main/java/org/traccar/config/Keys.java" @@ -72,6 +72,31 @@ def get_html(): ) +def get_pug(): + return ("\n").join( + [ + f""" div(class='card mt-3') + div(class='card-body') + h5(class='card-title') {x["key"]} #[span(class='badge badge-dark') config] + p(class='card-text') {"#[br] ".join(x["description"])}""" + for x in get_config_keys() + ] + ) + + if __name__ == "__main__": - html = get_html() - print(html) + parser = argparse.ArgumentParser( + description="Parses Keys.java to extract keys to be used in configuration files" + ) + parser.add_argument( + "--format", choices=["pug", "html"], default="pug", help="default: 'pug'" + ) + args = parser.parse_args() + + def get_output(): + if args.format == 'html': + return get_html() + + return get_pug() + + print(get_output()) \ No newline at end of file -- cgit v1.2.3 From 36202715301e365af212112d22059125adaea92a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 3 Jan 2022 18:25:33 -0800 Subject: Implement JIDO T63 protocol --- setup/default.xml | 1 + .../java/org/traccar/protocol/JidoProtocol.java | 39 +++++++ .../org/traccar/protocol/JidoProtocolDecoder.java | 128 +++++++++++++++++++++ .../traccar/protocol/JidoProtocolDecoderTest.java | 21 ++++ 4 files changed, 189 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/JidoProtocol.java create mode 100644 src/main/java/org/traccar/protocol/JidoProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index a592bbbed..fdb4cbf3b 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -308,5 +308,6 @@ 5234 5235 5236 + 5237 diff --git a/src/main/java/org/traccar/protocol/JidoProtocol.java b/src/main/java/org/traccar/protocol/JidoProtocol.java new file mode 100644 index 000000000..2a2e71dbe --- /dev/null +++ b/src/main/java/org/traccar/protocol/JidoProtocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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 JidoProtocol extends BaseProtocol { + + public JidoProtocol() { + 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 JidoProtocolDecoder(JidoProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java b/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java new file mode 100644 index 000000000..40fa8864d --- /dev/null +++ b/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java @@ -0,0 +1,128 @@ +/* + * Copyright 2021 Anton Tananaev (anton@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 JidoProtocolDecoder extends BaseProtocolDecoder { + + public JidoProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("*") + .number("(d+),") // imei + .number("(d+),") // command + .expression("([AV]),").optional() // validity + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(d+)(dd.d+),") // latitude + .expression("([NS]),") + .number("(d+)(dd.d+),") // longitude + .expression("([EW]),") + .groupBegin() + .number("(d+),") // speed + .number("(d+),") // odometer + .number("(d+),") // course + .number("(-?d+),") // altitude + .number("(d+),") // satellites + .number("d+,") // gsm 1 + .number("d+,") // gsm 2 + .number("([01]),") // charging + .number("(d+),") // battery level + .expression("([YKN]),") // mode + .number("([01]),") // lock + .number("[^,]+,") // accelerometer x + .number("[^,]+,") // accelerometer y + .number("[^,]+,") // accelerometer z + .or() + .expression("[^,]*,") // data + .groupEnd() + .number("xx") // checksum + .compile(); + + private String decodeAlarm(int type) { + switch (type) { + case 3: + return Position.ALARM_LOW_BATTERY; + case 4: + return Position.ALARM_TAMPERING; + default: + return null; + } + } + + @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.set(Position.KEY_ALARM, decodeAlarm(parser.nextInt())); + + if (parser.hasNext()) { + position.setValid(parser.next().equals("A")); + } else { + position.setValid(true); + } + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + + if (parser.hasNext(9)) { + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + + position.set(Position.KEY_ODOMETER, parser.nextInt()); + + position.setCourse(parser.nextInt()); + position.setAltitude(parser.nextInt()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_CHARGE, parser.nextInt() > 0); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + position.set("mode", parser.next()); + position.set(Position.KEY_BLOCKED, parser.nextInt() > 0); + + } + + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java new file mode 100644 index 000000000..9e01d7d68 --- /dev/null +++ b/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class JidoProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new JidoProtocolDecoder(null); + + verifyPosition(decoder, text( + "*12345678910101000,01,A,130517,160435,1820.5845,N,07833.2478,E,20,0,067,045,05,28,26,1,075,Y,1,0000,0000,0000,59")); + + verifyPosition(decoder, text( + "*12345678910101000,03,130517,160435,1820.5845,N,07833.2478,E,1,58")); + + } + +} -- cgit v1.2.3 From d00eb7ebfdaf15bb9ec32011fc7953325f568e0a Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Tue, 4 Jan 2022 20:20:21 +0100 Subject: feat: Totem - basic support for SMS and GPRS commands --- .../java/org/traccar/protocol/TotemProtocol.java | 9 +++- .../org/traccar/protocol/TotemProtocolEncoder.java | 36 ++++--------- .../traccar/protocol/TotemProtocolSmsEncoder.java | 59 ++++++++++++++++++++++ .../traccar/protocol/TotemProtocolEncoderTest.java | 18 ++++++- 4 files changed, 93 insertions(+), 29 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java diff --git a/src/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java index 7cf30475b..ecf7c858a 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocol.java +++ b/src/main/java/org/traccar/protocol/TotemProtocol.java @@ -25,7 +25,7 @@ import org.traccar.model.Command; public class TotemProtocol extends BaseProtocol { public TotemProtocol() { - setSupportedDataCommands( + String[] supportedCommands = new String[]{ Command.TYPE_CUSTOM, Command.TYPE_REBOOT_DEVICE, Command.TYPE_FACTORY_RESET, @@ -33,7 +33,12 @@ public class TotemProtocol extends BaseProtocol { Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_RESUME, Command.TYPE_ENGINE_STOP - ); + }; + setSupportedDataCommands(supportedCommands); + + setTextCommandEncoder(new TotemProtocolSmsEncoder(this)); + setSupportedTextCommands(supportedCommands); + addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java index 4717c3920..ab2584e9e 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java @@ -1,12 +1,11 @@ /* - * Copyright 2015 Irving Gonzalez - * Copyright 2015 - 2019 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,40 +15,27 @@ */ package org.traccar.protocol; -import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; import org.traccar.Protocol; +import org.traccar.helper.Checksum; -public class TotemProtocolEncoder extends StringProtocolEncoder { +public class TotemProtocolEncoder extends TotemProtocolSmsEncoder { public TotemProtocolEncoder(Protocol protocol) { super(protocol); } + private String encodeCommand(String commandString) { + String builtCommand = String.format("$$%04dCF%s", 10 + commandString.getBytes().length, commandString); + return String.format("%s%02X", builtCommand, Checksum.xor(builtCommand)); + } + @Override - protected Object encodeCommand(Command command) { + protected String encodeCommand(Command command) { initDevicePassword(command, "000000"); - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, "*%s,%s#", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "*%s,006#", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_FACTORY_RESET: - return formatCommand(command, "*%s,007#", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_GET_VERSION: - return formatCommand(command, "*%s,056#", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "*%s,012#", Command.KEY_DEVICE_PASSWORD); - // Assuming PIN 8 (Output C) is the power wire, like manual says but it can be PIN 5,7,8 - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "*%s,025,C,1#", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "*%s,025,C,0#", Command.KEY_DEVICE_PASSWORD); - default: - return null; - } + return encodeCommand(super.getCommandString(command)); } } diff --git a/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java new file mode 100644 index 000000000..2384b9730 --- /dev/null +++ b/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015 Irving Gonzalez + * 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. + * 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.Protocol; + +public class TotemProtocolSmsEncoder extends StringProtocolEncoder { + + public TotemProtocolSmsEncoder(Protocol protocol) { + super(protocol); + } + + protected String getCommandString(Command command) { + switch (command.getType()) { + case Command.TYPE_CUSTOM: + return formatCommand(command, "%s,%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); + case Command.TYPE_REBOOT_DEVICE: + return formatCommand(command, "%s,006", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_FACTORY_RESET: + return formatCommand(command, "%s,007", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_GET_VERSION: + return formatCommand(command, "%s,056", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_POSITION_SINGLE: + return formatCommand(command, "%s,012", Command.KEY_DEVICE_PASSWORD); + // Assuming PIN 8 (Output C) is the power wire, like manual says but it can be PIN 5,7,8 + case Command.TYPE_ENGINE_STOP: + return formatCommand(command, "%s,025,C,1", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_ENGINE_RESUME: + return formatCommand(command, "%s,025,C,0", Command.KEY_DEVICE_PASSWORD); + default: + return null; + } + } + + @Override + protected String encodeCommand(Command command) { + + initDevicePassword(command, "000000"); + + return String.format("*%s#", getCommandString(command)); + } + +} diff --git a/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java index 51e5bac92..a4fca2d9e 100644 --- a/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java @@ -15,10 +15,24 @@ public class TotemProtocolEncoderTest extends ProtocolTest { Command command = new Command(); command.setDeviceId(2); - command.setType(Command.TYPE_ENGINE_STOP); + command.setType(Command.TYPE_REBOOT_DEVICE); command.set(Command.KEY_DEVICE_PASSWORD, "000000"); - assertEquals("*000000,025,C,1#", encoder.encodeCommand(command)); + assertEquals("$$0020CF000000,0061D", encoder.encodeCommand(command)); + + } + + @Test + public void testSmsEncode() throws Exception { + + var encoder = new TotemProtocolSmsEncoder(null); + + Command command = new Command(); + command.setDeviceId(2); + command.setType(Command.TYPE_REBOOT_DEVICE); + command.set(Command.KEY_DEVICE_PASSWORD, "000000"); + + assertEquals("*000000,006#", encoder.encodeCommand(command)); } -- cgit v1.2.3 From 0ca865602a9d14004a2385e37af31a8d2976a5d7 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Tue, 4 Jan 2022 20:39:55 +0100 Subject: chore: Re-add copyright notice that was deleted by accident. --- src/main/java/org/traccar/protocol/TotemProtocolEncoder.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java index ab2584e9e..c8c0d5f37 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java @@ -1,4 +1,5 @@ /* + * Copyright 2015 Irving Gonzalez * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); -- cgit v1.2.3 From 1a32d6b9b7253716d5927200db12d287b134ee26 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Tue, 4 Jan 2022 21:38:01 +0100 Subject: fix: PR Feedback - Work In Progress --- .../java/org/traccar/protocol/TotemProtocol.java | 15 ++++++--- .../org/traccar/protocol/TotemProtocolEncoder.java | 38 +++++++++++++++++----- .../traccar/protocol/TotemProtocolSmsEncoder.java | 29 ++--------------- 3 files changed, 44 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java index ecf7c858a..417a4d6b0 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocol.java +++ b/src/main/java/org/traccar/protocol/TotemProtocol.java @@ -25,7 +25,7 @@ import org.traccar.model.Command; public class TotemProtocol extends BaseProtocol { public TotemProtocol() { - String[] supportedCommands = new String[]{ + setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_REBOOT_DEVICE, Command.TYPE_FACTORY_RESET, @@ -33,11 +33,18 @@ public class TotemProtocol extends BaseProtocol { Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_RESUME, Command.TYPE_ENGINE_STOP - }; - setSupportedDataCommands(supportedCommands); + ); setTextCommandEncoder(new TotemProtocolSmsEncoder(this)); - setSupportedTextCommands(supportedCommands); + setSupportedTextCommands( + Command.TYPE_CUSTOM, + Command.TYPE_REBOOT_DEVICE, + Command.TYPE_FACTORY_RESET, + Command.TYPE_GET_VERSION, + Command.TYPE_POSITION_SINGLE, + Command.TYPE_ENGINE_RESUME, + Command.TYPE_ENGINE_STOP + ); addServer(new TrackerServer(false, getName()) { @Override diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java index c8c0d5f37..ee1d1ede7 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java @@ -1,12 +1,12 @@ /* * Copyright 2015 Irving Gonzalez - * Copyright 2016 - 2019 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -16,27 +16,49 @@ */ package org.traccar.protocol; +import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; import org.traccar.Protocol; import org.traccar.helper.Checksum; -public class TotemProtocolEncoder extends TotemProtocolSmsEncoder { +public class TotemProtocolEncoder extends StringProtocolEncoder { public TotemProtocolEncoder(Protocol protocol) { super(protocol); } - private String encodeCommand(String commandString) { - String builtCommand = String.format("$$%04dCF%s", 10 + commandString.getBytes().length, commandString); - return String.format("%s%02X", builtCommand, Checksum.xor(builtCommand)); + protected String getCommandString(Command command) { + switch (command.getType()) { + case Command.TYPE_CUSTOM: + return formatCommand(command, "%s,%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); + case Command.TYPE_REBOOT_DEVICE: + return formatCommand(command, "%s,006", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_FACTORY_RESET: + return formatCommand(command, "%s,007", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_GET_VERSION: + return formatCommand(command, "%s,056", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_POSITION_SINGLE: + return formatCommand(command, "%s,012", Command.KEY_DEVICE_PASSWORD); + // Assuming PIN 8 (Output C) is the power wire, like manual says but it can be PIN 5,7,8 + case Command.TYPE_ENGINE_STOP: + return formatCommand(command, "%s,025,C,1", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_ENGINE_RESUME: + return formatCommand(command, "%s,025,C,0", Command.KEY_DEVICE_PASSWORD); + default: + return null; + } } @Override - protected String encodeCommand(Command command) { + protected Object encodeCommand(Command command) { initDevicePassword(command, "000000"); - return encodeCommand(super.getCommandString(command)); + String commandString = getCommandString(command); + String builtCommand = String.format("$$%04dCF%s", 10 + commandString.getBytes().length, commandString); + + return String.format("%s%02X", builtCommand, Checksum.xor(builtCommand)); + } } diff --git a/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java index 2384b9730..28180b33b 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java @@ -16,44 +16,21 @@ */ package org.traccar.protocol; -import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; import org.traccar.Protocol; -public class TotemProtocolSmsEncoder extends StringProtocolEncoder { +public class TotemProtocolSmsEncoder extends TotemProtocolEncoder { public TotemProtocolSmsEncoder(Protocol protocol) { super(protocol); } - protected String getCommandString(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, "%s,%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "%s,006", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_FACTORY_RESET: - return formatCommand(command, "%s,007", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_GET_VERSION: - return formatCommand(command, "%s,056", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "%s,012", Command.KEY_DEVICE_PASSWORD); - // Assuming PIN 8 (Output C) is the power wire, like manual says but it can be PIN 5,7,8 - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "%s,025,C,1", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "%s,025,C,0", Command.KEY_DEVICE_PASSWORD); - default: - return null; - } - } - @Override - protected String encodeCommand(Command command) { + protected Object encodeCommand(Command command) { initDevicePassword(command, "000000"); - return String.format("*%s#", getCommandString(command)); + return String.format("*%s#", super.getCommandString(command)); } } -- cgit v1.2.3 From c21626223cd0c480725d8057a2cd4bf2b9d7e0b3 Mon Sep 17 00:00:00 2001 From: Matjaž Črnko Date: Tue, 4 Jan 2022 22:09:43 +0100 Subject: fix: Totem - refactor formatContent so that it does not use non-static formatCommand function anymore. --- .../org/traccar/protocol/TotemProtocolEncoder.java | 21 ++++++++++++--------- .../traccar/protocol/TotemProtocolSmsEncoder.java | 5 +++-- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java index ee1d1ede7..6792d61a5 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java @@ -27,23 +27,26 @@ public class TotemProtocolEncoder extends StringProtocolEncoder { super(protocol); } - protected String getCommandString(Command command) { + public static String formatContent(Command command) { switch (command.getType()) { case Command.TYPE_CUSTOM: - return formatCommand(command, "%s,%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); + return String.format("%s,%s", + command.getAttributes().get(Command.KEY_DEVICE_PASSWORD), + command.getAttributes().get(Command.KEY_DATA) + ); case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "%s,006", Command.KEY_DEVICE_PASSWORD); + return String.format("%s,006", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); case Command.TYPE_FACTORY_RESET: - return formatCommand(command, "%s,007", Command.KEY_DEVICE_PASSWORD); + return String.format("%s,007", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); case Command.TYPE_GET_VERSION: - return formatCommand(command, "%s,056", Command.KEY_DEVICE_PASSWORD); + return String.format("%s,056", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "%s,012", Command.KEY_DEVICE_PASSWORD); + return String.format("%s,012", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); // Assuming PIN 8 (Output C) is the power wire, like manual says but it can be PIN 5,7,8 case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "%s,025,C,1", Command.KEY_DEVICE_PASSWORD); + return String.format("%s,025,C,1", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "%s,025,C,0", Command.KEY_DEVICE_PASSWORD); + return String.format("%s,025,C,0", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); default: return null; } @@ -54,7 +57,7 @@ public class TotemProtocolEncoder extends StringProtocolEncoder { initDevicePassword(command, "000000"); - String commandString = getCommandString(command); + String commandString = formatContent(command); String builtCommand = String.format("$$%04dCF%s", 10 + commandString.getBytes().length, commandString); return String.format("%s%02X", builtCommand, Checksum.xor(builtCommand)); diff --git a/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java index 28180b33b..8656f8a5c 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolSmsEncoder.java @@ -16,10 +16,11 @@ */ package org.traccar.protocol; +import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; import org.traccar.Protocol; -public class TotemProtocolSmsEncoder extends TotemProtocolEncoder { +public class TotemProtocolSmsEncoder extends StringProtocolEncoder { public TotemProtocolSmsEncoder(Protocol protocol) { super(protocol); @@ -30,7 +31,7 @@ public class TotemProtocolSmsEncoder extends TotemProtocolEncoder { initDevicePassword(command, "000000"); - return String.format("*%s#", super.getCommandString(command)); + return String.format("*%s#", TotemProtocolEncoder.formatContent(command)); } } -- cgit v1.2.3 From 6a6b3f601078eacad5cb92ed78afcad3543f667f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Jan 2022 20:55:19 -0800 Subject: Fix license notice --- src/main/java/org/traccar/protocol/H02ProtocolEncoder.java | 2 +- src/main/java/org/traccar/protocol/TotemProtocolEncoder.java | 2 +- src/main/java/org/traccar/protocol/WondexProtocolEncoder.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java index 7a765332c..8f1a8c042 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java @@ -6,7 +6,7 @@ * 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 + * 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, diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java index 4717c3920..a6fd8e9c3 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java @@ -6,7 +6,7 @@ * 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 + * 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, diff --git a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java index 21f1ee321..fb213dc40 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java @@ -5,7 +5,7 @@ * 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 + * 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, -- cgit v1.2.3 From ed02f30d6c770eb8ee47062ac007007450702d26 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Jan 2022 22:11:03 -0800 Subject: Support Prime ATW (G7) format --- .../traccar/protocol/Gl200TextProtocolDecoder.java | 21 ++++++++++++++------- .../protocol/Gl200TextProtocolDecoderTest.java | 4 ++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 683ba476e..7ce0c425d 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -139,7 +139,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(x+)?,") // lac .number("(x+)?,") // cid .groupEnd() - .number("(?:d+|(d+.d))?,") // odometer + .number("(?:d+|(d+.d))?,") // rssi / odometer .compile(); private static final Pattern PATTERN_OBD = new PatternBuilder() @@ -184,7 +184,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .expression("(?:([0-9A-Z]{17}),)?") // vin .expression("[^,]*,") // device name .number("(d+)?,") // power - .number("d{1,2},").optional() // report type + .number("(d{1,2}),").optional() // report type .number("d{1,2},").optional() // count .number("d*,").optional() // reserved .number("(d+),").optional() // battery @@ -208,11 +208,11 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(?:d+.?d*|Inf|NaN)?,") // fuel consumption .number("(d+)?,") // fuel level .or() - .number("(d{1,7}.d)?,").optional() // odometer - .number("(d{1,3})?,") // battery - .or() .number("(-?d),") // rssi .number("(d{1,3}),") // battery + .or() + .number("(d{1,7}.d)?,").optional() // odometer + .number("(d{1,3})?,") // battery .groupEnd() .any() .number("(dddd)(dd)(dd)") // date (yyyymmdd) @@ -835,6 +835,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { String vin = parser.next(); Integer power = parser.nextInt(); + Integer reportType = parser.nextInt(); Integer battery = parser.nextInt(); Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); @@ -877,12 +878,18 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RPM, parser.nextInt()); position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); + if (parser.hasNext(2)) { + if (reportType != null) { + position.set(Position.KEY_MOTION, BitUtil.check(reportType, 0)); + position.set(Position.KEY_CHARGE, BitUtil.check(reportType, 1)); + } + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + } if (parser.hasNext()) { 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) { diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 8978f64e5..9fab7e010 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = new Gl200TextProtocolDecoder(null); + verifyAttribute(decoder, buffer( + "+RESP:GTFRI,423031,866873025895726,,0,1,1,0,1,16,0.0,351,51.6,121.391063,31.164633,20181212072535,460,00,1877,DAE,00,3,85,20181212072535,002C$"), + Position.KEY_BATTERY_LEVEL, 85); + verifyAttributes(decoder, buffer( "+RESP:GTINF,DC0103,865284049247079,gv600mg,21,89883070000007211665,22,0,11,12913,12917,4.26,0,1,,,20210216154607,1,79,,01,00,,,20210216104606,1EBE$")); -- cgit v1.2.3 From d69662c28f031e0579211de4d8535c028324acb0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 5 Jan 2022 19:47:47 -0800 Subject: Fix validity decoding --- src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index b15688df0..d554c2999 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -411,7 +411,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(status, 6)) { - position.setValid(!BitUtil.check(status, 7)); + position.setValid(true); position.setTime(readDate(buf)); position.setAltitude(buf.readFloatLE()); position.setLongitude(buf.readFloatLE()); -- cgit v1.2.3 From 0ab8827dcfd144727f8470008f71fc49fa67618c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 6 Jan 2022 23:15:37 -0800 Subject: Send time response --- .../org/traccar/protocol/HuabaoProtocolDecoder.java | 17 ++++++++++++++++- .../org/traccar/protocol/HuabaoProtocolDecoderTest.java | 3 +++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index aa85ea061..0ae08af37 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -34,7 +34,10 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Calendar; +import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.TimeZone; @@ -149,7 +152,19 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; if (buf.getByte(buf.readerIndex()) == '(') { - return decodeResult(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII)); + String sentence = buf.toString(StandardCharsets.US_ASCII); + if (sentence.contains("BASE,2")) { + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + String response = sentence.replace("TIME", dateFormat.format(new Date())); + if (channel != null) { + channel.writeAndFlush(new NetworkMessage( + Unpooled.copiedBuffer(response, StandardCharsets.US_ASCII), remoteAddress)); + } + return null; + } else { + return decodeResult(channel, remoteAddress, sentence); + } } buf.readUnsignedByte(); // start marker diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 238799fac..7aaec33e7 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = new HuabaoProtocolDecoder(null); + verifyNull(decoder, buffer( + "(794104004140,1,001,BASE,2,TIME)")); + verifyNull(decoder, binary( "7E01000021013345678906000F002C012F373031313142534A2D4D3742203030303030303001D4C1423838383838B47E")); -- cgit v1.2.3 From 8ceefb941be5109a402ec55cda5a65f3555fd204 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 9 Jan 2022 23:30:16 -0800 Subject: Support eeLink version 2.2 --- .../org/traccar/protocol/EelinkProtocolDecoder.java | 20 +++++++++++++++++++- .../traccar/protocol/EelinkProtocolDecoderTest.java | 6 +++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index 8fe12fe69..9856ad999 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -218,6 +218,24 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(7); // bss2 } + if (BitUtil.check(flags, 7)) { + buf.readUnsignedByte(); // radio access technology + int count = buf.readUnsignedByte(); + if (count > 0) { + buf.readUnsignedShort(); // mcc + buf.readUnsignedShort(); // mnc + buf.readUnsignedShort(); // lac + buf.readUnsignedShort(); // tac + buf.readUnsignedInt(); // cid + buf.readUnsignedShort(); // ta + } + for (int i = 0; i < count; i++) { + buf.readUnsignedShort(); // physical cid + buf.readUnsignedShort(); // e-arfcn + buf.readUnsignedByte(); // rssi + } + } + if (type == MSG_WARNING) { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); diff --git a/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java index d0c683abf..c1cc3c39a 100644 --- a/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "454c029249a50354679090044671676712004321315f3cf43503fc94d3760c79328a0129000000000a01f9000190330905580d2e046f118a04ec00000000ccc7086c02fe000000000000000000000000000000000000676712004321325f3cf43e03fc94d3760c79328a0129000000000901f9000190330905580d2e046f117b04ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321335f3cf44703fc94d3760c79328a0129000000000901f9000190330905580d2e046f117f04ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321345f3cf45303fc94d3760c79328a0129000000000901f9000190330905580d2e046f119d04ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321355f3cf45c03fc94d3760c79328a0129000000000801f9000190330905580d2e046f11a304ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321365f3cf46603fc94d3760c79328a0129000000000801f9000190330905580d2e046f118804df00000000ccc7086d02ff000000000000000000000000000000000000676712004321375f3cf47103fc94d3760c79328a0129000000000901f9000190330905580d2e046f119704ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321385f3cf47a03fc94d3760c79328a0129000000000901f9000190330905580d2e046f118204ec00000000ccc7086e0300000000000000000000000000000000000000676712004321395f3cf48303fc94d3760c79328a0129000000000901f9000190330905580d2e046f117604df00000000ccc7086e0300000000000000000000000000000000000000")); + verifyPosition(decoder, binary( + "6767120056096661d38e0091fbf0aa3a0f8fa08500060051015f09002542e50e7ea6080101f90001304e304e0818390d000000c524c2ae0699102b00000000000115b0040504050000000014000000000000000000000000000002")); + verifyAttribute(decoder, binary( "676714001500035f74a2940201360104591100a7160122250400"), Position.KEY_ALARM, Position.ALARM_REMOVING); @@ -42,9 +45,6 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, binary( "676714002414B05AD43A7D03026B92B10C395499FFD7000000000701CC00002495000014203604067B")); - verifyNotNull(decoder, binary( - "676714004F14B0E68CAFE58AA8E68AA5E8ADA621E5B9BFE4B89CE79C81E6B7B1E59CB3E5B882E58D97E5B1B1E58CBAE696B0E8A5BFE8B7AF3138EFBC88E8B79DE5AE87E998B3E5A4A7E58EA63230E7B1B3EFBC89")); - verifyPosition(decoder, binary( "676780005a000001000000004c61743a4e33312e38333935352c4c6f6e3a5738322e36313334362c436f757273653a302e30302c53706565643a302e30306b6d2f682c4461746554696d653a323031372d31322d30322031313a32393a3433")); -- cgit v1.2.3 From 847960abb40e37c598af082e96a742ca745a7ff5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 10 Jan 2022 23:58:30 -0800 Subject: Implement ARTE Armoli protocol --- setup/default.xml | 1 + .../java/org/traccar/protocol/ArmoliProtocol.java | 39 ++++++++ .../traccar/protocol/ArmoliProtocolDecoder.java | 102 +++++++++++++++++++++ .../protocol/ArmoliProtocolDecoderTest.java | 24 +++++ 4 files changed, 166 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/ArmoliProtocol.java create mode 100644 src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index fdb4cbf3b..f8cbc9e41 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -309,5 +309,6 @@ 5235 5236 5237 + 5238 diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java new file mode 100644 index 000000000..2571690c2 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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 ArmoliProtocol extends BaseProtocol { + + public ArmoliProtocol() { + 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 ArmoliProtocolDecoder(ArmoliProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java new file mode 100644 index 000000000..46bdb484e --- /dev/null +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java @@ -0,0 +1,102 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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 ArmoliProtocolDecoder extends BaseProtocolDecoder { + + public ArmoliProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("[M") // start + .number("(d{15})") // imei + .number("(dd)(dd)(dd)") // date (ddmmyy) + .number("(dd)(dd)(dd)") // time (hhmmss) + .number("([NS])(dd.d{6})") // latitude + .number("([EW])(ddd.d{6})") // longitude + .number("(d)") // valid + .number("(x)") // satellites + .number("(xx)") // speed + .number("(ddd)") // course + .number("(xxx)") // adc 1 + .number("(xxx)") // adc 2 + .number("(xx)") // status + .number("(xx)") // max speed + .number("(x{6})") // distance + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + char type = sentence.charAt(1); + + if (type != 'M') { + if (channel != null && (type == 'Q' || type == 'L')) { + channel.writeAndFlush(new NetworkMessage("[TX,];;", remoteAddress)); + } + return null; + } + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setValid(parser.nextInt() > 0); + + position.set(Position.KEY_SATELLITES, parser.nextHexInt()); + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextHexInt())); + position.setCourse(parser.nextInt()); + + position.set(Position.PREFIX_ADC + 1, parser.nextHexInt() / 27.0 * 1000); + position.set(Position.PREFIX_ADC + 1, parser.nextHexInt() / 27.0 * 1000); + position.set(Position.KEY_STATUS, parser.nextHexInt()); + position.set("maxSpeed", parser.nextHexInt()); + position.set(Position.KEY_ODOMETER, parser.nextHexInt()); + + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java new file mode 100644 index 000000000..0851b1e05 --- /dev/null +++ b/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java @@ -0,0 +1,24 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class ArmoliProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new ArmoliProtocolDecoder(null); + + verifyNull(decoder, text( + "[Q010001088610010024363698990011101070608200,05XXXXXXXXX,10.49.182.53,C,1,20,19,0];")); + + verifyPosition(decoder, text( + "[M860906041293587100122061310N40.792751E029.4313092801143000000010003513209FFGC18080H8DA#E209C4];")); + + verifyNull(decoder, text( + "[L866104027971681];")); + + } + +} -- cgit v1.2.3 From 7b2e47a143a34cb97cb8b52c00081e36898db346 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 11 Jan 2022 23:10:35 -0800 Subject: Fix frame decoding --- src/main/java/org/traccar/protocol/ArmoliProtocol.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java index 2571690c2..1b8ce871c 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocol.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -15,10 +15,10 @@ */ 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.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; @@ -28,7 +28,7 @@ public class ArmoliProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new LineBasedFrameDecoder(1024)); + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new ArmoliProtocolDecoder(ArmoliProtocol.this)); -- cgit v1.2.3 From ad102cd882dd9ec6f7e4ffedad34c793184ea23b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 11 Jan 2022 23:36:47 -0800 Subject: Add FlexAPI motion decoding --- .../java/org/traccar/protocol/FlexApiProtocolDecoder.java | 13 ++++++++++++- .../org/traccar/protocol/FlexApiProtocolDecoderTest.java | 5 ++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index d4d539a9e..3dfcd459b 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@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,17 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_VIN, payload.getString("obd.vin")); } + } else if (topic.contains("motion")) { + + getLastLocation(position, new Date(payload.getInt("motion.ts") * 1000L)); + + position.set("ax", payload.getJsonNumber("motion.ax").doubleValue()); + position.set("ay", payload.getJsonNumber("motion.ay").doubleValue()); + position.set("az", payload.getJsonNumber("motion.az").doubleValue()); + position.set("gx", payload.getJsonNumber("motion.gx").doubleValue()); + position.set("gy", payload.getJsonNumber("motion.gy").doubleValue()); + position.set("gz", payload.getJsonNumber("motion.gz").doubleValue()); + } else { return null; diff --git a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java index a276a01e9..43b4e097f 100644 --- a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class FlexApiProtocolDecoderTest extends ProtocolTest { var decoder = new FlexApiProtocolDecoder(null); + verifyAttributes(decoder, text( + "${\"topic\":\"v1/VF3102021113001/motion/info\",\"payload\":{\"motion.ts\":1641885877,\"motion.ax\":0.006344,\"motion.ay\":0.289384,\"motion.az\":-0.939156,\"motion.gx\":0.420000,\"motion.gy\":0.420000,\"motion.gz\":-0.280000}}xx")); + verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021113001/gnss/info\",\"payload\":{\"gnss.ts\":1639713510,\"gnss.latitude\":30.587509,\"gnss.longitude\":104.053650,\"gnss.altitude\":391,\"gnss.speed\":0,\"gnss.heading\":0,\"gnss.hdop\":1.100000,\"gnss.fix\":4,\"gnss.num_sv\":10}}xx")); @@ -25,7 +28,7 @@ public class FlexApiProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "${\"topic\":\"v1/VF3102021111601/gnss/info\",\"payload\":{\"time\":1637225390,\"lat\":30.587942,\"log\":104.053543,\"gnss.altitude\":480.399994,\"gnss.speed\":0,\"gnss.heading\":0,\"gnss.hdop\":0.900000,\"gnss.fix\":4,\"gnss.num_sv\":11}}xx")); - verifyNull(decoder, text( + verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021111601/motion/info\",\"payload\":{\"motion.ts\":1637225450,\"motion.ax\":0.009272,\"motion.ay\":0.278404,\"motion.az\":-0.941596,\"motion.gx\":0.420000,\"motion.gy\":-0.490000,\"motion.gz\":0.140000}}xx")); verifyNull(decoder, text( -- cgit v1.2.3 From 9453cb6f684b26cc87a8d81c46b714319ff0cbaa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 12 Jan 2022 22:03:44 -0800 Subject: Support iStartek OBD data --- .../traccar/protocol/StartekProtocolDecoder.java | 30 +++++++++++++++++----- .../protocol/StartekProtocolDecoderTest.java | 3 +++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index 042518cb2..c1869def2 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,14 +70,23 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .number("(x+),") // outputs .number("(x+)|") // power .number("(x+)") // battery - .groupBegin() - .text("|") - .expression("([^,]+)").optional() // adc + .expression("([^,]+)?") // adc .groupBegin() .text(",") .number("d,") // extended .expression("([^,]+)?,") // fuel - .expression("([^,]+)?,?") // temperature + .expression("([^,]+)?") // temperature + .groupBegin() + .text(",") + .number("(d+)|") // rpm + .number("(d+)|") // engine load + .number("d+|") // maf flow + .number("d+|") // intake pressure + .number("d+|") // intake temperature + .number("(d+)|") // throttle + .number("(d+)|") // coolant temperature + .number("(d+)|") // instant fuel + .number("(d+)") // fuel level .groupEnd("?") .groupEnd("?") .any() @@ -181,7 +190,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { String[] adc = parser.next().split("\\|"); - for (int i = 0; i < adc.length; i++) { + for (int i = 1; i < adc.length; i++) { position.set(Position.PREFIX_ADC + (i + 1), Integer.parseInt(adc[i], 16) * 0.01); } } @@ -208,6 +217,15 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { } } + if (parser.hasNext(6)) { + position.set(Position.KEY_RPM, parser.nextInt()); + position.set(Position.KEY_ENGINE_LOAD, parser.nextInt()); + position.set(Position.KEY_THROTTLE, parser.nextInt()); + position.set(Position.KEY_COOLANT_TEMP, parser.nextInt() - 40); + position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextInt() * 0.1); + position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); + } + return position; } diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index 5d22344fa..6c2d39940 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class StartekProtocolDecoderTest extends ProtocolTest { var decoder = new StartekProtocolDecoder(null); + verifyPosition(decoder, text( + "&&R187,860294046453690,000,0,,220105160656,A,22.994986,72.499711,15,0.9,2,222,55,121135784,404|98|147B|0000376A,24,0000001F,02,00,052E|01A3|0000|0000,1,010000|020000,,853|6|10|105|73|41|125|34|52")); + verifyPosition(decoder, text( "&&o142,860262050066062,000,27,,211111070826,V,28.653435,-106.077455,0,0.0,0,151,1412,918,0|0|4708|01402D19,6,0000001A,02,00,04C0|016C|0000|0000,1,,,BB")); -- cgit v1.2.3 From 839751e76e329adb573150644bd6198beba0d3b6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Jan 2022 23:31:03 -0800 Subject: Decode remaining FlexAPI data --- .../traccar/protocol/FlexApiProtocolDecoder.java | 51 ++++++++++++++++++++-- .../protocol/FlexApiProtocolDecoderTest.java | 8 ++-- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index 3dfcd459b..20ff78c21 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -19,6 +19,8 @@ import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.Protocol; +import org.traccar.model.CellTower; +import org.traccar.model.Network; import org.traccar.model.Position; import javax.json.Json; @@ -52,7 +54,7 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { JsonObject payload = root.getJsonObject("payload"); - if (topic.contains("gnss")) { + if (topic.contains("/gnss/")) { position.setValid(true); @@ -72,7 +74,25 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, payload.getInt("gnss.num_sv")); - } else if (topic.contains("obd")) { + } else if (topic.contains("/cellular1/")) { + + getLastLocation(position, new Date(payload.getInt("modem1.ts") * 1000L)); + + position.set("imei", payload.getString("modem1.imei")); + position.set("imsi", payload.getString("modem1.imsi")); + position.set(Position.KEY_ICCID, payload.getString("modem1.iccid")); + + String operator = payload.getString("modem1.operator"); + if (!operator.isEmpty()) { + position.setNetwork(new Network(CellTower.from( + Integer.parseInt(operator.substring(0, 3)), + Integer.parseInt(operator.substring(3)), + Integer.parseInt(payload.getString("modem1.lac"), 16), + Integer.parseInt(payload.getString("modem1.cell_id"), 16), + payload.getInt("modem1.rssi")))); + } + + } else if (topic.contains("/obd/")) { getLastLocation(position, new Date(payload.getInt("obd.ts") * 1000L)); @@ -89,7 +109,7 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_VIN, payload.getString("obd.vin")); } - } else if (topic.contains("motion")) { + } else if (topic.contains("/motion/")) { getLastLocation(position, new Date(payload.getInt("motion.ts") * 1000L)); @@ -100,6 +120,31 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { position.set("gy", payload.getJsonNumber("motion.gy").doubleValue()); position.set("gz", payload.getJsonNumber("motion.gz").doubleValue()); + } else if (topic.contains("/io/")) { + + getLastLocation(position, new Date(payload.getInt("io.ts") * 1000L)); + + if (payload.containsKey("io.IGN")) { + position.set(Position.KEY_IGNITION, payload.getInt("io.IGN") > 0); + } + + for (String key : payload.keySet()) { + if (key.startsWith("io.AI")) { + position.set(Position.PREFIX_ADC + key.substring(5), payload.getJsonNumber(key).doubleValue()); + } else if (key.startsWith("io.DI") && !key.endsWith("_pullup")) { + position.set(Position.PREFIX_IN + key.substring(5), payload.getInt(key) > 0); + } else if (key.startsWith("io.DO")) { + position.set(Position.PREFIX_OUT + key.substring(5), payload.getInt(key) > 0); + } + } + + } else if (topic.contains("/sysinfo/")) { + + getLastLocation(position, new Date(payload.getInt("sysinfo.ts") * 1000L)); + + position.set("serial", payload.getString("sysinfo.serial_number")); + position.set(Position.KEY_VERSION_FW, payload.getString("sysinfo.firmware_version")); + } else { return null; diff --git a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java index 43b4e097f..c819cd8bf 100644 --- a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java @@ -16,7 +16,7 @@ public class FlexApiProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021113001/gnss/info\",\"payload\":{\"gnss.ts\":1639713510,\"gnss.latitude\":30.587509,\"gnss.longitude\":104.053650,\"gnss.altitude\":391,\"gnss.speed\":0,\"gnss.heading\":0,\"gnss.hdop\":1.100000,\"gnss.fix\":4,\"gnss.num_sv\":10}}xx")); - verifyNull(decoder, text( + verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021113001/cellular1/info\",\"payload\":{\"modem1.ts\":1639713510,\"modem1.imei\":\"863674047326655\",\"modem1.imsi\":\"\",\"modem1.iccid\":\"\",\"modem1.phone_num\":\"\",\"modem1.signal_lvl\":0,\"modem1.reg_status\":0,\"modem1.operator\":\"\",\"modem1.network\":0,\"modem1.lac\":\"\",\"modem1.cell_id\":\"\",\"modem1.rssi\":0,\"modem1.rsrp\":0,\"modem1.rsrq\":0,\"cellular1.status\":2,\"cellular1.ip\":\"0.0.0.0\",\"cellular1.netmask\":\"255.255.255.255\",\"cellular1.gateway\":\"0.0.0.0\",\"cellular1.dns1\":\"0.0.0.0\",\"cellular1.up_at\":602}}xx")); verifyAttributes(decoder, text( @@ -31,13 +31,13 @@ public class FlexApiProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021111601/motion/info\",\"payload\":{\"motion.ts\":1637225450,\"motion.ax\":0.009272,\"motion.ay\":0.278404,\"motion.az\":-0.941596,\"motion.gx\":0.420000,\"motion.gy\":-0.490000,\"motion.gz\":0.140000}}xx")); - verifyNull(decoder, text( + verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021111601/sysinfo/info\",\"payload\":{\"sysinfo.ts\":1637224740,\"sysinfo.model_name\":\"310\",\"sysinfo.oem_name\":\"inhand\",\"sysinfo.serial_number\":\"VF3102021111601\",\"sysinfo.firmware_version\":\"VT3_V1.1.32\",\"sysinfo.product_number\":\"FQ58\",\"sysinfo.description\":\"www.inhand.com.cn\"}}xx")); - verifyNull(decoder, text( + verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021111601/io/info\",\"payload\":{\"io.ts\":1637227722,\"io.AI1\":0,\"io.DI1\":1,\"io.DI2\":0,\"io.DI3\":0,\"io.DI4\":0,\"io.DI1_pullup\":0,\"io.DI2_pullup\":0,\"io.DI3_pullup\":0,\"io.DI4_pullup\":0,\"io.DO1\":0,\"io.DO2\":0,\"io.DO3\":0,\"io.IGT\":1}}xx")); - verifyNull(decoder, text( + verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021111601/cellular1/info\",\"payload\":{\"modem1.ts\":1637225330,\"modem1.imei\":\"863674047324999\",\"modem1.imsi\":\"460111150414721\",\"modem1.iccid\":\"89860319482086580401\",\"modem1.phone_num\":\"\",\"modem1.signal_lvl\":25,\"modem1.reg_status\":1,\"modem1.operator\":\"46011\",\"modem1.network\":3,\"modem1.lac\":\"EA00\",\"modem1.cell_id\":\"E779B81\",\"modem1.rssi\":0,\"modem1.rsrp\":0,\"modem1.rsrq\":0,\"cellular1.status\":3,\"cellular1.ip\":\"10.136.143.193\",\"cellular1.netmask\":\"255.255.255.255\",\"cellular1.gateway\":\"10.64.64.64\",\"cellular1.dns1\":\"223.5.5.5\",\"cellular1.up_at\":450}}xx")); } -- cgit v1.2.3 From c1121777969fc5f183e325ad672b581cbe881895 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Dec 2021 23:09:40 -0800 Subject: Extract connector interface --- src/main/java/org/traccar/BasePipelineFactory.java | 10 ++++---- src/main/java/org/traccar/BaseProtocol.java | 10 +++++--- src/main/java/org/traccar/Protocol.java | 2 +- src/main/java/org/traccar/ServerManager.java | 16 ++++++------ src/main/java/org/traccar/TrackerConnector.java | 30 ++++++++++++++++++++++ src/main/java/org/traccar/TrackerServer.java | 29 ++++++++++----------- .../org/traccar/handler/OpenChannelHandler.java | 14 +++++----- 7 files changed, 70 insertions(+), 41 deletions(-) create mode 100644 src/main/java/org/traccar/TrackerConnector.java diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index c9f3a2346..88a1bc713 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -54,12 +54,12 @@ import java.util.Map; public abstract class BasePipelineFactory extends ChannelInitializer { - private final TrackerServer server; + private final TrackerConnector connector; private final String protocol; private int timeout; - public BasePipelineFactory(TrackerServer server, String protocol) { - this.server = server; + public BasePipelineFactory(TrackerConnector connector, String protocol) { + this.connector = connector; this.protocol = protocol; timeout = Context.getConfig().getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); if (timeout == 0) { @@ -97,10 +97,10 @@ public abstract class BasePipelineFactory extends ChannelInitializer { protected void initChannel(Channel channel) { final ChannelPipeline pipeline = channel.pipeline(); - if (timeout > 0 && !server.isDatagram()) { + if (timeout > 0 && !connector.isDatagram()) { pipeline.addLast(new IdleStateHandler(timeout, 0, 0)); } - pipeline.addLast(new OpenChannelHandler(server)); + pipeline.addLast(new OpenChannelHandler(connector)); pipeline.addLast(new NetworkMessageHandler()); pipeline.addLast(new StandardLoggingHandler(protocol)); diff --git a/src/main/java/org/traccar/BaseProtocol.java b/src/main/java/org/traccar/BaseProtocol.java index bd3391822..2fca9432e 100644 --- a/src/main/java/org/traccar/BaseProtocol.java +++ b/src/main/java/org/traccar/BaseProtocol.java @@ -35,7 +35,7 @@ public abstract class BaseProtocol implements Protocol { private final String name; private final Set supportedDataCommands = new HashSet<>(); private final Set supportedTextCommands = new HashSet<>(); - private final List serverList = new LinkedList<>(); + private final List connectorList = new LinkedList<>(); private StringProtocolEncoder textCommandEncoder = null; @@ -54,12 +54,14 @@ public abstract class BaseProtocol implements Protocol { } protected void addServer(TrackerServer server) { - serverList.add(server); + connectorList.add(server); } + // TODO addClient + @Override - public Collection getServerList() { - return serverList; + public Collection getConnectorList() { + return connectorList; } public void setSupportedDataCommands(String... commands) { diff --git a/src/main/java/org/traccar/Protocol.java b/src/main/java/org/traccar/Protocol.java index aea69b353..bc9c99557 100644 --- a/src/main/java/org/traccar/Protocol.java +++ b/src/main/java/org/traccar/Protocol.java @@ -25,7 +25,7 @@ public interface Protocol { String getName(); - Collection getServerList(); + Collection getConnectorList(); Collection getSupportedDataCommands(); diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 935a821aa..45ac656f3 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2021 Anton Tananaev (anton@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,7 +39,7 @@ public class ServerManager { private static final Logger LOGGER = LoggerFactory.getLogger(ServerManager.class); - private final List serverList = new LinkedList<>(); + private final List connectorList = new LinkedList<>(); private final Map protocolList = new ConcurrentHashMap<>(); private void loadPackage(String packageName) throws IOException, URISyntaxException, ReflectiveOperationException { @@ -75,7 +75,7 @@ public class ServerManager { if (BaseProtocol.class.isAssignableFrom(protocolClass) && Context.getConfig().hasKey( Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { BaseProtocol protocol = (BaseProtocol) protocolClass.getDeclaredConstructor().newInstance(); - serverList.addAll(protocol.getServerList()); + connectorList.addAll(protocol.getConnectorList()); protocolList.put(protocol.getName(), protocol); } } @@ -90,18 +90,18 @@ public class ServerManager { } public void start() throws Exception { - for (TrackerServer server: serverList) { + for (TrackerConnector connector: connectorList) { try { - server.start(); + connector.start(); } catch (BindException e) { - LOGGER.warn("Port {} is disabled due to conflict", server.getPort()); + LOGGER.warn("Port disabled due to conflict", e); } } } public void stop() { - for (TrackerServer server: serverList) { - server.stop(); + for (TrackerConnector connector: connectorList) { + connector.stop(); } GlobalTimer.release(); } diff --git a/src/main/java/org/traccar/TrackerConnector.java b/src/main/java/org/traccar/TrackerConnector.java new file mode 100644 index 000000000..9fc5e0f62 --- /dev/null +++ b/src/main/java/org/traccar/TrackerConnector.java @@ -0,0 +1,30 @@ +/* + * Copyright 2021 Anton Tananaev (anton@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; + +import io.netty.channel.group.ChannelGroup; + +public interface TrackerConnector { + + boolean isDatagram(); + + ChannelGroup getChannelGroup(); + + void start() throws Exception; + + void stop(); + +} diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index 59ba123e2..7b25e5cc5 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,11 +28,19 @@ import org.traccar.config.Keys; import java.net.InetSocketAddress; -public abstract class TrackerServer { +public abstract class TrackerServer implements TrackerConnector { private final boolean datagram; + + @SuppressWarnings("rawtypes") private final AbstractBootstrap bootstrap; + private final int port; + private final String address; + + private final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); + + @Override public boolean isDatagram() { return datagram; } @@ -69,32 +77,20 @@ public abstract class TrackerServer { protected abstract void addProtocolHandlers(PipelineBuilder pipeline); - private int port; - public int getPort() { return port; } - public void setPort(int port) { - this.port = port; - } - - private String address; - public String getAddress() { return address; } - public void setAddress(String address) { - this.address = address; - } - - private final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); - + @Override public ChannelGroup getChannelGroup() { return channelGroup; } + @Override public void start() throws Exception { InetSocketAddress endpoint; if (address == null) { @@ -109,6 +105,7 @@ public abstract class TrackerServer { } } + @Override public void stop() { channelGroup.close().awaitUninterruptibly(); } diff --git a/src/main/java/org/traccar/handler/OpenChannelHandler.java b/src/main/java/org/traccar/handler/OpenChannelHandler.java index d09d617ab..e416f35ae 100644 --- a/src/main/java/org/traccar/handler/OpenChannelHandler.java +++ b/src/main/java/org/traccar/handler/OpenChannelHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2021 Anton Tananaev (anton@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,26 +17,26 @@ package org.traccar.handler; import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelHandlerContext; -import org.traccar.TrackerServer; +import org.traccar.TrackerConnector; public class OpenChannelHandler extends ChannelDuplexHandler { - private final TrackerServer server; + private final TrackerConnector connector; - public OpenChannelHandler(TrackerServer server) { - this.server = server; + public OpenChannelHandler(TrackerConnector connector) { + this.connector = connector; } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { super.channelActive(ctx); - server.getChannelGroup().add(ctx.channel()); + connector.getChannelGroup().add(ctx.channel()); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { super.channelInactive(ctx); - server.getChannelGroup().remove(ctx.channel()); + connector.getChannelGroup().remove(ctx.channel()); } } -- cgit v1.2.3 From 93745ce5de3f5004cb98d951794c692db284a2e2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 9 Jan 2022 23:27:54 -0800 Subject: Start client implementation --- src/main/java/org/traccar/BasePipelineFactory.java | 4 +- src/main/java/org/traccar/TrackerClient.java | 85 ++++++++++++++++++++++ src/main/java/org/traccar/TrackerServer.java | 6 +- src/main/java/org/traccar/config/Keys.java | 9 ++- 4 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/traccar/TrackerClient.java diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 88a1bc713..d50852649 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,7 +70,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { protected abstract void addProtocolHandlers(PipelineBuilder pipeline); @SafeVarargs - private final void addHandlers(ChannelPipeline pipeline, Class... handlerClasses) { + private void addHandlers(ChannelPipeline pipeline, Class... handlerClasses) { for (Class handlerClass : handlerClasses) { if (handlerClass != null) { pipeline.addLast(Main.getInjector().getInstance(handlerClass)); diff --git a/src/main/java/org/traccar/TrackerClient.java b/src/main/java/org/traccar/TrackerClient.java new file mode 100644 index 000000000..d86dc43e1 --- /dev/null +++ b/src/main/java/org/traccar/TrackerClient.java @@ -0,0 +1,85 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.util.concurrent.GlobalEventExecutor; +import org.traccar.config.Keys; + +import java.util.List; + +public abstract class TrackerClient implements TrackerConnector { + + private final Bootstrap bootstrap; + + private final int port; + private final String address; + private final String[] devices; + + private final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); + + @Override + public boolean isDatagram() { + return false; + } + + public TrackerClient(String protocol) { + + address = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); + port = Context.getConfig().getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol)); + devices = Context.getConfig().getString(Keys.PROTOCOL_DEVICES.withPrefix(protocol)).split("[, ]"); + + BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, protocol) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + TrackerClient.this.addProtocolHandlers(pipeline); + } + }; + + bootstrap = new Bootstrap() + .group(EventLoopGroupFactory.getWorkerGroup()) + .channel(NioSocketChannel.class) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel channel) { + pipelineFactory.initChannel(channel); + } + }); + } + + protected abstract void addProtocolHandlers(PipelineBuilder pipeline); + + @Override + public ChannelGroup getChannelGroup() { + return channelGroup; + } + + @Override + public void start() throws Exception { + bootstrap.connect(address, port).sync(); + } + + @Override + public void stop() { + channelGroup.close().awaitUninterruptibly(); + } + +} diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index 7b25e5cc5..caae6c585 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,14 +60,14 @@ public abstract class TrackerServer implements TrackerConnector { if (datagram) { - this.bootstrap = new Bootstrap() + bootstrap = new Bootstrap() .group(EventLoopGroupFactory.getWorkerGroup()) .channel(NioDatagramChannel.class) .handler(pipelineFactory); } else { - this.bootstrap = new ServerBootstrap() + bootstrap = new ServerBootstrap() .group(EventLoopGroupFactory.getBossGroup(), EventLoopGroupFactory.getWorkerGroup()) .channel(NioServerSocketChannel.class) .childHandler(pipelineFactory); diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index e8e0ff207..8f93b21c1 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@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,6 +37,13 @@ public final class Keys { ".port", Collections.singletonList(KeyType.GLOBAL)); + /** + * List of devices for polling protocols. List should contain unique ids separated by commas. + */ + public static final ConfigSuffix PROTOCOL_DEVICES = new ConfigSuffix<>( + ".devices", + Collections.singletonList(KeyType.GLOBAL)); + /** * Connection timeout value in seconds. Because sometimes there is no way to detect lost TCP connection old * connections stay in open state. On most systems there is a limit on number of open connection, so this leads to -- cgit v1.2.3 From 0ce163ba62cc991fee56d9c05fca41c9f7a28143 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jan 2022 23:19:23 -0800 Subject: Finish initial implementation --- src/main/java/org/traccar/BasePipelineFactory.java | 4 ++ src/main/java/org/traccar/BaseProtocol.java | 4 +- src/main/java/org/traccar/BaseProtocolPoller.java | 56 ++++++++++++++++++ src/main/java/org/traccar/ServerManager.java | 5 +- src/main/java/org/traccar/TrackerClient.java | 66 +++++++++++++++++---- src/main/java/org/traccar/TrackerConnector.java | 4 +- src/main/java/org/traccar/TrackerServer.java | 24 +++++++- src/main/java/org/traccar/config/Keys.java | 31 +++++++++- .../java/org/traccar/protocol/OrbcommProtocol.java | 40 +++++++++++++ .../traccar/protocol/OrbcommProtocolDecoder.java | 57 ++++++++++++++++++ .../traccar/protocol/OrbcommProtocolPoller.java | 69 ++++++++++++++++++++++ src/test/java/org/traccar/ProtocolTest.java | 6 ++ .../protocol/OrbcommProtocolDecoderTest.java | 18 ++++++ 13 files changed, 366 insertions(+), 18 deletions(-) create mode 100644 src/main/java/org/traccar/BaseProtocolPoller.java create mode 100644 src/main/java/org/traccar/protocol/OrbcommProtocol.java create mode 100644 src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java create mode 100644 src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java create mode 100644 src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index d50852649..89ef76a80 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -67,6 +67,8 @@ public abstract class BasePipelineFactory extends ChannelInitializer { } } + protected abstract void addTransportHandlers(PipelineBuilder pipeline); + protected abstract void addProtocolHandlers(PipelineBuilder pipeline); @SafeVarargs @@ -97,6 +99,8 @@ public abstract class BasePipelineFactory extends ChannelInitializer { protected void initChannel(Channel channel) { final ChannelPipeline pipeline = channel.pipeline(); + addTransportHandlers(pipeline::addLast); + if (timeout > 0 && !connector.isDatagram()) { pipeline.addLast(new IdleStateHandler(timeout, 0, 0)); } diff --git a/src/main/java/org/traccar/BaseProtocol.java b/src/main/java/org/traccar/BaseProtocol.java index 2fca9432e..52d34dc44 100644 --- a/src/main/java/org/traccar/BaseProtocol.java +++ b/src/main/java/org/traccar/BaseProtocol.java @@ -57,7 +57,9 @@ public abstract class BaseProtocol implements Protocol { connectorList.add(server); } - // TODO addClient + protected void addClient(TrackerClient client) { + connectorList.add(client); + } @Override public Collection getConnectorList() { diff --git a/src/main/java/org/traccar/BaseProtocolPoller.java b/src/main/java/org/traccar/BaseProtocolPoller.java new file mode 100644 index 000000000..88138577c --- /dev/null +++ b/src/main/java/org/traccar/BaseProtocolPoller.java @@ -0,0 +1,56 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.util.concurrent.Future; +import org.traccar.config.Keys; + +import java.net.SocketAddress; +import java.util.concurrent.TimeUnit; + +public abstract class BaseProtocolPoller extends ChannelDuplexHandler { + + private final long interval; + private Future timeout; + + public BaseProtocolPoller(Protocol protocol) { + interval = Context.getConfig().getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol.getName())); + } + + protected abstract void sendRequest(Channel channel, SocketAddress remoteAddress); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + super.channelActive(ctx); + if (interval > 0) { + timeout = ctx.executor().scheduleAtFixedRate( + () -> sendRequest(ctx.channel(), ctx.channel().remoteAddress()), 0, interval, TimeUnit.SECONDS); + } + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + super.channelInactive(ctx); + if (timeout != null) { + timeout.cancel(false); + timeout = null; + } + } + +} diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 45ac656f3..0db786bdb 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import org.traccar.config.Keys; import java.io.File; import java.io.IOException; import java.net.BindException; +import java.net.ConnectException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; @@ -95,6 +96,8 @@ public class ServerManager { connector.start(); } catch (BindException e) { LOGGER.warn("Port disabled due to conflict", e); + } catch (ConnectException e) { + LOGGER.warn("Connection failed", e); } } } diff --git a/src/main/java/org/traccar/TrackerClient.java b/src/main/java/org/traccar/TrackerClient.java index d86dc43e1..dda02f909 100644 --- a/src/main/java/org/traccar/TrackerClient.java +++ b/src/main/java/org/traccar/TrackerClient.java @@ -16,18 +16,24 @@ package org.traccar; import io.netty.bootstrap.Bootstrap; -import io.netty.channel.ChannelInitializer; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; -import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.ssl.SslHandler; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.GlobalEventExecutor; import org.traccar.config.Keys; -import java.util.List; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import java.util.concurrent.TimeUnit; public abstract class TrackerClient implements TrackerConnector { + private final boolean secure; + private final long interval; + private final Bootstrap bootstrap; private final int port; @@ -41,31 +47,54 @@ public abstract class TrackerClient implements TrackerConnector { return false; } + @Override + public boolean isSecure() { + return secure; + } + public TrackerClient(String protocol) { + secure = Context.getConfig().getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); + interval = Context.getConfig().getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol)); address = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); - port = Context.getConfig().getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol)); + port = Context.getConfig().getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol), secure ? 443 : 80); devices = Context.getConfig().getString(Keys.PROTOCOL_DEVICES.withPrefix(protocol)).split("[, ]"); BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, protocol) { + @Override + protected void addTransportHandlers(PipelineBuilder pipeline) { + try { + if (isSecure()) { + SSLEngine engine = SSLContext.getDefault().createSSLEngine(); + engine.setUseClientMode(true); + pipeline.addLast(new SslHandler(engine)); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - TrackerClient.this.addProtocolHandlers(pipeline); + try { + TrackerClient.this.addProtocolHandlers(pipeline); + } catch (Exception e) { + throw new RuntimeException(e); + } } }; bootstrap = new Bootstrap() .group(EventLoopGroupFactory.getWorkerGroup()) .channel(NioSocketChannel.class) - .handler(new ChannelInitializer() { - @Override - protected void initChannel(SocketChannel channel) { - pipelineFactory.initChannel(channel); - } - }); + .handler(pipelineFactory); } - protected abstract void addProtocolHandlers(PipelineBuilder pipeline); + protected abstract void addProtocolHandlers(PipelineBuilder pipeline) throws Exception; + + public String[] getDevices() { + return devices; + } @Override public ChannelGroup getChannelGroup() { @@ -74,7 +103,18 @@ public abstract class TrackerClient implements TrackerConnector { @Override public void start() throws Exception { - bootstrap.connect(address, port).sync(); + bootstrap.connect(address, port) + .syncUninterruptibly().channel().closeFuture().addListener(new GenericFutureListener<>() { + @Override + public void operationComplete(Future future) { + if (interval > 0) { + GlobalEventExecutor.INSTANCE.schedule(() -> { + bootstrap.connect(address, port) + .syncUninterruptibly().channel().closeFuture().addListener(this); + }, interval, TimeUnit.SECONDS); + } + } + }); } @Override diff --git a/src/main/java/org/traccar/TrackerConnector.java b/src/main/java/org/traccar/TrackerConnector.java index 9fc5e0f62..9e2d27ae5 100644 --- a/src/main/java/org/traccar/TrackerConnector.java +++ b/src/main/java/org/traccar/TrackerConnector.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,8 @@ public interface TrackerConnector { boolean isDatagram(); + boolean isSecure(); + ChannelGroup getChannelGroup(); void start() throws Exception; diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index caae6c585..8e2fce616 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -23,14 +23,18 @@ import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; import io.netty.channel.socket.nio.NioDatagramChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.ssl.SslHandler; import io.netty.util.concurrent.GlobalEventExecutor; import org.traccar.config.Keys; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; import java.net.InetSocketAddress; public abstract class TrackerServer implements TrackerConnector { private final boolean datagram; + private final boolean secure; @SuppressWarnings("rawtypes") private final AbstractBootstrap bootstrap; @@ -45,13 +49,31 @@ public abstract class TrackerServer implements TrackerConnector { return datagram; } + @Override + public boolean isSecure() { + return secure; + } + public TrackerServer(boolean datagram, String protocol) { this.datagram = datagram; + secure = Context.getConfig().getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); address = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); port = Context.getConfig().getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol)); BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, protocol) { + @Override + protected void addTransportHandlers(PipelineBuilder pipeline) { + try { + if (isSecure()) { + SSLEngine engine = SSLContext.getDefault().createSSLEngine(); + pipeline.addLast(new SslHandler(engine)); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { TrackerServer.this.addProtocolHandlers(pipeline); @@ -99,7 +121,7 @@ public abstract class TrackerServer implements TrackerConnector { endpoint = new InetSocketAddress(address, port); } - Channel channel = bootstrap.bind(endpoint).sync().channel(); + Channel channel = bootstrap.bind(endpoint).syncUninterruptibly().channel(); if (channel != null) { getChannelGroup().add(channel); } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 8f93b21c1..cb3bd4de8 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -38,12 +38,27 @@ public final class Keys { Collections.singletonList(KeyType.GLOBAL)); /** - * List of devices for polling protocols. List should contain unique ids separated by commas. + * List of devices for polling protocols. List should contain unique ids separated by commas. Used only for polling + * protocols. */ public static final ConfigSuffix PROTOCOL_DEVICES = new ConfigSuffix<>( ".devices", Collections.singletonList(KeyType.GLOBAL)); + /** + * Polling interval in seconds. Used only for polling protocols. + */ + public static final ConfigSuffix PROTOCOL_INTERVAL = new ConfigSuffix<>( + ".interval", + Collections.singletonList(KeyType.GLOBAL)); + + /** + * Enable SSL support for the protocol. Not all protocols support this. + */ + public static final ConfigSuffix PROTOCOL_SSL = new ConfigSuffix<>( + ".ssl", + Collections.singletonList(KeyType.GLOBAL)); + /** * Connection timeout value in seconds. Because sometimes there is no way to detect lost TCP connection old * connections stay in open state. On most systems there is a limit on number of open connection, so this leads to @@ -182,6 +197,20 @@ public final class Keys { ".ignoreSessionCache", Collections.singletonList(KeyType.GLOBAL)); + /** + * ORBCOMM API access id. + */ + public static final ConfigKey ORBCOMM_ACCESS_ID = new ConfigKey<>( + "orbcomm.accessId", + Collections.singletonList(KeyType.GLOBAL)); + + /** + * ORBCOMM API password. + */ + public static final ConfigKey ORBCOMM_PASSWORD = new ConfigKey<>( + "orbcomm.password", + Collections.singletonList(KeyType.GLOBAL)); + /** * Skip device connection session cache. Global configuration. */ diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocol.java b/src/main/java/org/traccar/protocol/OrbcommProtocol.java new file mode 100644 index 000000000..bdfce3b1e --- /dev/null +++ b/src/main/java/org/traccar/protocol/OrbcommProtocol.java @@ -0,0 +1,40 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestEncoder; +import io.netty.handler.codec.http.HttpResponseDecoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerClient; + +public class OrbcommProtocol extends BaseProtocol { + + public OrbcommProtocol() { + addClient(new TrackerClient(getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new HttpRequestEncoder()); + pipeline.addLast(new HttpResponseDecoder()); + pipeline.addLast(new HttpObjectAggregator(65535)); + pipeline.addLast(new OrbcommProtocolDecoder(OrbcommProtocol.this)); + pipeline.addLast(new OrbcommProtocolPoller(OrbcommProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java new file mode 100644 index 000000000..8f828beff --- /dev/null +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -0,0 +1,57 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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 io.netty.handler.codec.http.FullHttpResponse; +import org.traccar.BasePipelineFactory; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Protocol; + +import javax.json.Json; +import javax.json.JsonObject; +import java.io.StringReader; +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +public class OrbcommProtocolDecoder extends BaseProtocolDecoder { + + public OrbcommProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + FullHttpResponse response = (FullHttpResponse) msg; + String content = response.content().toString(StandardCharsets.UTF_8); + JsonObject json = Json.createReader(new StringReader(content)).readObject(); + + OrbcommProtocolPoller poller = BasePipelineFactory.getHandler(channel.pipeline(), OrbcommProtocolPoller.class); + if (poller != null) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + poller.setStartTime(dateFormat.parse(json.getString("NextStartUTC"))); + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java new file mode 100644 index 000000000..87fa039e1 --- /dev/null +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java @@ -0,0 +1,69 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.Unpooled; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.handler.codec.http.QueryStringEncoder; +import org.traccar.BaseProtocolPoller; +import org.traccar.Context; +import org.traccar.Protocol; +import org.traccar.config.Keys; + +import java.net.SocketAddress; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class OrbcommProtocolPoller extends BaseProtocolPoller { + + private final String accessId; + private final String password; + + private Date startTime = new Date(); + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public OrbcommProtocolPoller(Protocol protocol) { + super(protocol); + accessId = Context.getConfig().getString(Keys.ORBCOMM_ACCESS_ID); + password = Context.getConfig().getString(Keys.ORBCOMM_PASSWORD); + } + + @Override + protected void sendRequest(Channel channel, SocketAddress remoteAddress) { + + QueryStringEncoder encoder = new QueryStringEncoder("/GLGW/2/RestMessages.svc/JSON/get_return_messages/"); + encoder.addParam("access_id", accessId); + encoder.addParam("password", password); + + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + encoder.addParam("start_utc", dateFormat.format(startTime)); + + HttpRequest request = new DefaultFullHttpRequest( + HttpVersion.HTTP_1_1, HttpMethod.POST, encoder.toString(), Unpooled.buffer()); + channel.writeAndFlush(request); + } + +} diff --git a/src/test/java/org/traccar/ProtocolTest.java b/src/test/java/org/traccar/ProtocolTest.java index c40a15dcc..353593c29 100644 --- a/src/test/java/org/traccar/ProtocolTest.java +++ b/src/test/java/org/traccar/ProtocolTest.java @@ -4,9 +4,11 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.DefaultHttpHeaders; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import org.traccar.helper.DataConverter; import org.traccar.model.CellTower; @@ -89,6 +91,10 @@ public class ProtocolTest extends BaseTest { return new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, method, url, Unpooled.buffer(), headers, new DefaultHttpHeaders()); } + protected DefaultFullHttpResponse response(ByteBuf data) { + return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, data); + } + protected void verifyNotNull(BaseProtocolDecoder decoder, Object object) throws Exception { assertNotNull(decoder.decode(null, null, object)); } diff --git a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java new file mode 100644 index 000000000..fe84c1af4 --- /dev/null +++ b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class OrbcommProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new OrbcommProtocolDecoder(null); + + verifyNull(decoder, response( + buffer("{\"ErrorID\":0,\"NextStartUTC\":\"2016-10-13 15:19:59\",\"Messages\":[{\"ID\":120213064,\"MessageUTC\":\"2016-10-12 12:42:01\",\"ReceiveUTC\":\"2016-10-12 12:42:01\",\"SIN\":0,\"MobileID\":\"01173096SKY0E45\",\"Payload\":{\"Name\":\"modemRegistration\",\"SIN\":0,\"MIN\":0,\"Fields\":[{\"Name\":\"hardwareMajorVersion\",\"Value\":\"4\"},{\"Name\":\"hardwareMinorVersion\",\"Value\":\"2\"},{\"Name\":\"softwareMajorVersion\",\"Value\":\"13\"},{\"Name\":\"softwareMinorVersion\",\"Value\":\"1\"},{\"Name\":\"product\",\"Value\":\"4\"},{\"Name\":\"wakeupPeriod\",\"Value\":\"None\"},{\"Name\":\"lastResetReason\",\"Value\":\"Software\"},{\"Name\":\"virtualCarrier\",\"Value\":\"6\"},{\"Name\":\"beam\",\"Value\":\"1\"},{\"Name\":\"vain\",\"Value\":\"0\"},{\"Name\":\"reserved\",\"Value\":\"0\"},{\"Name\":\"operatorTxState\",\"Value\":\"0\"},{\"Name\":\"userTxState\",\"Value\":\"0\"},{\"Name\":\"broadcastIDCount\",\"Value\":\"0\"}}],\"RegionName\":\"AMERRB11\",\"OTAMessageSize\":15,\"CustomerID\":0}]}"))); + + } + +} -- cgit v1.2.3 From 93a341b3232863161f9422beae34f0782dc86a29 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jan 2022 23:39:46 -0800 Subject: Fix test --- src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java index fe84c1af4..9cf841676 100644 --- a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java @@ -11,7 +11,7 @@ public class OrbcommProtocolDecoderTest extends ProtocolTest { var decoder = new OrbcommProtocolDecoder(null); verifyNull(decoder, response( - buffer("{\"ErrorID\":0,\"NextStartUTC\":\"2016-10-13 15:19:59\",\"Messages\":[{\"ID\":120213064,\"MessageUTC\":\"2016-10-12 12:42:01\",\"ReceiveUTC\":\"2016-10-12 12:42:01\",\"SIN\":0,\"MobileID\":\"01173096SKY0E45\",\"Payload\":{\"Name\":\"modemRegistration\",\"SIN\":0,\"MIN\":0,\"Fields\":[{\"Name\":\"hardwareMajorVersion\",\"Value\":\"4\"},{\"Name\":\"hardwareMinorVersion\",\"Value\":\"2\"},{\"Name\":\"softwareMajorVersion\",\"Value\":\"13\"},{\"Name\":\"softwareMinorVersion\",\"Value\":\"1\"},{\"Name\":\"product\",\"Value\":\"4\"},{\"Name\":\"wakeupPeriod\",\"Value\":\"None\"},{\"Name\":\"lastResetReason\",\"Value\":\"Software\"},{\"Name\":\"virtualCarrier\",\"Value\":\"6\"},{\"Name\":\"beam\",\"Value\":\"1\"},{\"Name\":\"vain\",\"Value\":\"0\"},{\"Name\":\"reserved\",\"Value\":\"0\"},{\"Name\":\"operatorTxState\",\"Value\":\"0\"},{\"Name\":\"userTxState\",\"Value\":\"0\"},{\"Name\":\"broadcastIDCount\",\"Value\":\"0\"}}],\"RegionName\":\"AMERRB11\",\"OTAMessageSize\":15,\"CustomerID\":0}]}"))); + buffer("{\"ErrorID\":0,\"NextStartUTC\":\"2016-10-13 15:19:59\",\"Messages\":[{\"ID\":120213064,\"MessageUTC\":\"2016-10-12 12:42:01\",\"ReceiveUTC\":\"2016-10-12 12:42:01\",\"SIN\":0,\"MobileID\":\"01173096SKY0E45\",\"Payload\":{\"Name\":\"modemRegistration\",\"SIN\":0,\"MIN\":0,\"Fields\":[{\"Name\":\"hardwareMajorVersion\",\"Value\":\"4\"},{\"Name\":\"hardwareMinorVersion\",\"Value\":\"2\"},{\"Name\":\"softwareMajorVersion\",\"Value\":\"13\"},{\"Name\":\"softwareMinorVersion\",\"Value\":\"1\"},{\"Name\":\"product\",\"Value\":\"4\"},{\"Name\":\"wakeupPeriod\",\"Value\":\"None\"},{\"Name\":\"lastResetReason\",\"Value\":\"Software\"},{\"Name\":\"virtualCarrier\",\"Value\":\"6\"},{\"Name\":\"beam\",\"Value\":\"1\"},{\"Name\":\"vain\",\"Value\":\"0\"},{\"Name\":\"reserved\",\"Value\":\"0\"},{\"Name\":\"operatorTxState\",\"Value\":\"0\"},{\"Name\":\"userTxState\",\"Value\":\"0\"},{\"Name\":\"broadcastIDCount\",\"Value\":\"0\"}],\"RegionName\":\"AMERRB11\",\"OTAMessageSize\":15,\"CustomerID\":0}}]}"))); } -- cgit v1.2.3 From 071f038906ebcd29a42803e32ffe65efde57dbb6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jan 2022 23:45:02 -0800 Subject: Handle null pointer --- .../java/org/traccar/protocol/OrbcommProtocolDecoder.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index 8f828beff..daef923b0 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -44,11 +44,14 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { String content = response.content().toString(StandardCharsets.UTF_8); JsonObject json = Json.createReader(new StringReader(content)).readObject(); - OrbcommProtocolPoller poller = BasePipelineFactory.getHandler(channel.pipeline(), OrbcommProtocolPoller.class); - if (poller != null) { - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - poller.setStartTime(dateFormat.parse(json.getString("NextStartUTC"))); + if (channel != null) { + OrbcommProtocolPoller poller = + BasePipelineFactory.getHandler(channel.pipeline(), OrbcommProtocolPoller.class); + if (poller != null) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + poller.setStartTime(dateFormat.parse(json.getString("NextStartUTC"))); + } } return null; -- cgit v1.2.3 From bb6a73f97f87ce06dcc9f3b2b129b7fde657b22c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 16 Jan 2022 10:49:42 -0800 Subject: Add request headers --- src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java index 87fa039e1..9465f63a7 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.handler.codec.http.DefaultFullHttpRequest; +import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpVersion; @@ -37,6 +38,7 @@ public class OrbcommProtocolPoller extends BaseProtocolPoller { private final String accessId; private final String password; + private final String host; private Date startTime = new Date(); @@ -48,6 +50,7 @@ public class OrbcommProtocolPoller extends BaseProtocolPoller { super(protocol); accessId = Context.getConfig().getString(Keys.ORBCOMM_ACCESS_ID); password = Context.getConfig().getString(Keys.ORBCOMM_PASSWORD); + host = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol.getName())); } @Override @@ -63,6 +66,8 @@ public class OrbcommProtocolPoller extends BaseProtocolPoller { HttpRequest request = new DefaultFullHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.POST, encoder.toString(), Unpooled.buffer()); + request.headers().add(HttpHeaderNames.HOST, host); + request.headers().add(HttpHeaderNames.CONTENT_LENGTH, 0); channel.writeAndFlush(request); } -- cgit v1.2.3 From b1b70bd763c6c4e8a8011052e49c67b41e3b31c9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Jan 2022 17:10:15 -0800 Subject: Support Protrack VT03A/VT05S/VT08S --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 0dcdab892..ec09f371b 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -70,6 +70,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GPS_LBS_STATUS_3 = 0x27; public static final int MSG_LBS_MULTIPLE_1 = 0x28; public static final int MSG_LBS_MULTIPLE_2 = 0x2E; + public static final int MSG_LBS_MULTIPLE_3 = 0x24; public static final int MSG_LBS_WIFI = 0x2C; public static final int MSG_LBS_EXTEND = 0x18; public static final int MSG_LBS_STATUS = 0x19; @@ -699,8 +700,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; // space10x multi-lbs message - } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_EXTEND - || type == MSG_LBS_WIFI || type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5) { + } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_MULTIPLE_3 + || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI || type == MSG_LBS_2 + || type == MSG_WIFI_3 || type == MSG_WIFI_5) { boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5; @@ -726,7 +728,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // time leads - if (type != MSG_LBS_MULTIPLE_1 && type != MSG_LBS_MULTIPLE_2 && type != MSG_LBS_2) { + if (type != MSG_LBS_MULTIPLE_1 && type != MSG_LBS_MULTIPLE_2 && type != MSG_LBS_MULTIPLE_3 + && type != MSG_LBS_2) { int wifiCount = buf.readUnsignedByte(); for (int i = 0; i < wifiCount; i++) { String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); -- cgit v1.2.3 From 6d9ac4e9687320a8e3b48d526d6cc2c694388df6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Jan 2022 17:11:37 -0800 Subject: Add unit test case --- src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index d2d090c04..8aadb7fe3 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyNotNull(decoder, binary( + "78783B2810010D02020201CC00287D001F713E287D001F7231287D001E232D287D001F4018000000000000000000000000000000000000FF00020005B14B0D0A")); + verifyNotNull(decoder, binary( "78782111150b0b022c30c804b7af7808810cb0003c00012e02d075df0084890c000679950d0a")); -- cgit v1.2.3 From 3c5af6affc37ae0833e5d0560d86f85d60abf42e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Jan 2022 18:59:55 -0800 Subject: Update Java libraries --- build.gradle | 34 +++++++++++++-------------- src/main/java/org/traccar/model/Calendar.java | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index d9c70fc15..b7ce624c8 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id "java" id "checkstyle" - id "com.google.protobuf" version "0.8.16" + id "com.google.protobuf" version "0.8.18" id "org.kordamp.gradle.project-enforcer" version "0.9.0" } @@ -11,10 +11,10 @@ repositories { ext { guiceVersion = "5.0.1" - jettyVersion = "10.0.6" // jetty 11 javax to jakarta - jerseyVersion = "2.34" // jersey 3 javax to jakarta + jettyVersion = "10.0.7" // jetty 11 javax to jakarta + jerseyVersion = "2.35" // jersey 3 javax to jakarta jacksonVersion = "2.12.2" // same version as jersey-media-json-jackson dependency - protobufVersion = "3.17.3" + protobufVersion = "3.19.3" } sourceCompatibility = "11" @@ -22,7 +22,7 @@ compileJava.options.encoding = "UTF-8" jar.destinationDirectory = file("$projectDir/target") checkstyle { - toolVersion = "8.26" + toolVersion = "9.2.1" configFile = "gradle/checkstyle.xml" as File checkstyleTest.enabled = false } @@ -42,13 +42,13 @@ enforce { dependencies { implementation "commons-codec:commons-codec:1.15" - implementation "com.h2database:h2:1.4.200" - implementation "mysql:mysql-connector-java:8.0.26" - implementation "org.postgresql:postgresql:42.2.23" - implementation "com.microsoft.sqlserver:mssql-jdbc:9.4.0.jre11" - implementation "com.zaxxer:HikariCP:5.0.0" + implementation "com.h2database:h2:2.0.206" + implementation "mysql:mysql-connector-java:8.0.27" + implementation "org.postgresql:postgresql:42.3.1" + implementation "com.microsoft.sqlserver:mssql-jdbc:9.4.1.jre11" + implementation "com.zaxxer:HikariCP:5.0.1" implementation "io.netty:netty-all:4.1.66.Final" - implementation "org.slf4j:slf4j-jdk14:2.0.0-alpha4" + implementation "org.slf4j:slf4j-jdk14:2.0.0-alpha6" implementation "com.google.inject:guice:$guiceVersion" implementation "com.google.inject.extensions:guice-assistedinject:$guiceVersion" implementation "org.owasp.encoder:encoder:1.2.3" @@ -64,24 +64,24 @@ dependencies { implementation "org.glassfish.jersey.inject:jersey-hk2:$jerseyVersion" implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" - implementation "org.liquibase:liquibase-core:4.4.3" + implementation "org.liquibase:liquibase-core:4.7.0" implementation "com.sun.mail:javax.mail:1.6.2" implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) implementation "org.jxls:jxls-poi:1.0.16" // needs upgrade (wait for jexl 4) implementation "org.apache.velocity:velocity:1.7" implementation "org.apache.velocity:velocity-tools:2.0" implementation "org.apache.commons:commons-collections4:4.4" - implementation "org.mnode.ical4j:ical4j:3.0.29" + implementation "org.mnode.ical4j:ical4j:3.1.2" implementation "org.locationtech.spatial4j:spatial4j:0.8" - implementation "org.locationtech.jts:jts-core:1.18.1" - implementation "net.java.dev.jna:jna-platform:5.8.0" - implementation "com.github.jnr:jnr-posix:3.1.7" + implementation "org.locationtech.jts:jts-core:1.18.2" + implementation "net.java.dev.jna:jna-platform:5.10.0" + implementation "com.github.jnr:jnr-posix:3.1.15" implementation "com.google.protobuf:protobuf-java:$protobufVersion" implementation "javax.xml.bind:jaxb-api:2.3.1" implementation "com.sun.xml.bind:jaxb-core:3.0.2" implementation "com.sun.xml.bind:jaxb-impl:3.0.2" implementation "javax.activation:activation:1.1.1" - implementation 'com.amazonaws:aws-java-sdk-sns:1.12.47' + implementation "com.amazonaws:aws-java-sdk-sns:1.12.141" testImplementation "junit:junit:4.13.2" } diff --git a/src/main/java/org/traccar/model/Calendar.java b/src/main/java/org/traccar/model/Calendar.java index 1010325b6..0b45ca6c8 100644 --- a/src/main/java/org/traccar/model/Calendar.java +++ b/src/main/java/org/traccar/model/Calendar.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import net.fortuna.ical4j.data.CalendarBuilder; import net.fortuna.ical4j.data.ParserException; import net.fortuna.ical4j.filter.Filter; -import net.fortuna.ical4j.filter.PeriodRule; +import net.fortuna.ical4j.filter.predicate.PeriodRule; import net.fortuna.ical4j.model.DateTime; import net.fortuna.ical4j.model.Period; import net.fortuna.ical4j.model.component.CalendarComponent; -- cgit v1.2.3 From 9f16a90a99bada4b3ea7cad883485ac0a52e2184 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Jan 2022 20:39:35 -0800 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index b7ce624c8..b75ad6ff4 100644 --- a/build.gradle +++ b/build.gradle @@ -95,7 +95,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "4.14", + "Implementation-Version": "4.15", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 316bc757b..3ffab1289 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=4.14 +AppVersion=4.15 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index 5a77e4bf9..9882c92d7 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "4.14", + "version": "4.15", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From 0b4195174d2ecd627fc7beb518c968274e99ae4f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Jan 2022 20:52:33 -0800 Subject: Make integration test multithreaded --- tools/test-integration.py | 57 +++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/tools/test-integration.py b/tools/test-integration.py index 55bbf389f..6251b0d97 100755 --- a/tools/test-integration.py +++ b/tools/test-integration.py @@ -8,6 +8,7 @@ import urllib2 import json import socket import time +import threading messages = { 'gps103' : 'imei:123456789012345,help me,1201011201,,F,120100.000,A,6000.0000,N,13000.0000,E,0.00,;', @@ -141,6 +142,7 @@ def send_message(port, message): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', port)) s.send(message) + time.sleep(5) s.close() def get_protocols(cookie, device_id): @@ -155,40 +157,41 @@ def get_protocols(cookie, device_id): protocols.append(position['protocol']) return protocols -ports = load_ports() +if __name__ == "__main__": + ports = load_ports() -cookie = login() -remove_devices(cookie) - -devices = { - '123456789012345' : add_device(cookie, '123456789012345'), - '123456789012' : add_device(cookie, '123456789012'), - '1234567890' : add_device(cookie, '1234567890'), - '123456' : add_device(cookie, '123456'), - '1234' : add_device(cookie, '1234') -} + cookie = login() + remove_devices(cookie) + devices = { + '123456789012345' : add_device(cookie, '123456789012345'), + '123456789012' : add_device(cookie, '123456789012'), + '1234567890' : add_device(cookie, '1234567890'), + '123456' : add_device(cookie, '123456'), + '1234' : add_device(cookie, '1234') + } -all = set(ports.keys()) -protocols = set(messages.keys()) + all = set(ports.keys()) + protocols = set(messages.keys()) -print 'Total: %d' % len(all) -print 'Missing: %d' % len(all - protocols) -print 'Covered: %d' % len(protocols) + print 'Total: %d' % len(all) + print 'Missing: %d' % len(all - protocols) + print 'Covered: %d' % len(protocols) -#if all - protocols: -# print '\nMissing: %s\n' % repr(list((all - protocols))) + #if all - protocols: + # print '\nMissing: %s\n' % repr(list((all - protocols))) -for protocol in messages: - send_message(ports[protocol], messages[protocol]) + for protocol in messages: + thread = threading.Thread(target = send_message, args = (ports[protocol], messages[protocol])) + thread.start() -time.sleep(10) + time.sleep(10) -for device in devices: - protocols -= set(get_protocols(cookie, devices[device])) + for device in devices: + protocols -= set(get_protocols(cookie, devices[device])) -print 'Success: %d' % (len(messages) - len(protocols)) -print 'Failed: %d' % len(protocols) + print 'Success: %d' % (len(messages) - len(protocols)) + print 'Failed: %d' % len(protocols) -if protocols: - print '\nFailed: %s' % repr(list(protocols)) + if protocols: + print '\nFailed: %s' % repr(list(protocols)) -- cgit v1.2.3 From 5c7ac225688d025c0299bd63d595de78ed14e3cd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Jan 2022 21:35:12 -0800 Subject: Update JDK versions --- setup/environment.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/environment.sh b/setup/environment.sh index cb80a296a..86a50cc85 100644 --- a/setup/environment.sh +++ b/setup/environment.sh @@ -22,6 +22,6 @@ export PATH=$PATH:~/bin/Sencha/Cmd/ cd traccar/setup wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe -wget https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-debug-11.0.12.7-1/java-11-openjdk-debug-11.0.12.7-1.windows.ojdkbuild.x86_64.zip -wget https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.12%2B7/jdk-11.0.12-ojdkbuild-linux-x64.zip -wget https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.12%2B7/jdk-11.0.12-ojdkbuild-linux-armhf.zip +wget https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-11.0.13.8-1/java-11-openjdk-11.0.13.8-1.windows.ojdkbuild.x86_64.zip +wget https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-x64.zip +wget https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-armhf.zip -- cgit v1.2.3 From 27ff64d6ab93dc07dfec1ca155a559e07c9d0b93 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Jan 2022 22:19:13 -0800 Subject: Update submodule commit --- traccar-web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traccar-web b/traccar-web index aac829df8..9e1c0b441 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit aac829df866d4975fa52e2d42b4d197ec1f05d34 +Subproject commit 9e1c0b44189136ec6abf05720c698027a689fa08 -- cgit v1.2.3 From a872ad3dc4d9b9601790e324c7799caf43637525 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Jan 2022 23:48:25 -0800 Subject: Fix request method --- src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java index 9465f63a7..bf1093654 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java @@ -65,7 +65,7 @@ public class OrbcommProtocolPoller extends BaseProtocolPoller { encoder.addParam("start_utc", dateFormat.format(startTime)); HttpRequest request = new DefaultFullHttpRequest( - HttpVersion.HTTP_1_1, HttpMethod.POST, encoder.toString(), Unpooled.buffer()); + HttpVersion.HTTP_1_1, HttpMethod.GET, encoder.toString(), Unpooled.buffer()); request.headers().add(HttpHeaderNames.HOST, host); request.headers().add(HttpHeaderNames.CONTENT_LENGTH, 0); channel.writeAndFlush(request); -- cgit v1.2.3 From 5094cb914e0957b57f0986cdb004431ce45a85ad Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 18 Jan 2022 23:00:01 -0800 Subject: Use geocoding on request only --- setup/default.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/default.xml b/setup/default.xml index f8cbc9e41..0d8133627 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -18,6 +18,8 @@ nominatim https://us1.locationiq.com/v1/reverse.php pk.689d849289c8c63708068b2ff1f63b2d + true + true info ./logs/tracker-server.log -- cgit v1.2.3 From edd6f8c70370b80c9990710cdd2d1a0ca4509b7c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Jan 2022 23:14:08 -0800 Subject: Handle zero byte --- src/main/java/org/traccar/protocol/MiniFinderProtocol.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java index 82534ecd8..0cc9598ed 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ public class MiniFinderProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";\0", ";")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MiniFinderProtocolEncoder(MiniFinderProtocol.this)); -- cgit v1.2.3 From 6f1449a9e22f87c22369212c0094e02d813818c0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Jan 2022 20:11:04 -0800 Subject: Support PAW format --- .../traccar/protocol/MictrackProtocolDecoder.java | 25 ++++++++++++++-------- .../protocol/MictrackProtocolDecoderTest.java | 3 +++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java index 652ba3f6a..c72a742b9 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2020 Roeland Boeters (roeland@geodelta.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -114,14 +114,18 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeWifi(Network network, String data) { + private void decodeWifi(Network network, String data, boolean hasSsid) { 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]))); + int step = hasSsid ? 3 : 2; + int offset = hasSsid ? 1 : 0; + for (int i = 0; i < values.length / step; i++) { + network.addWifiAccessPoint(WifiAccessPoint.from( + values[i * step + offset], Integer.parseInt(values[i * step + offset + 1]))); } } - private void decodeNetwork(Position position, String data, boolean hasWifi, boolean hasCell) throws ParseException { + private void decodeNetwork( + Position position, String data, boolean hasWifi, boolean hasSsid, boolean hasCell) throws ParseException { int index = 0; String[] values = data.split("\\+"); @@ -130,7 +134,7 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder { Network network = new Network(); if (hasWifi) { - decodeWifi(network, values[index++]); + decodeWifi(network, values[index++], hasSsid); } if (hasCell) { @@ -231,19 +235,22 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, fragments[4]); break; case "R1": - decodeNetwork(position, fragments[4], true, false); + decodeNetwork(position, fragments[4], true, false, false); break; case "R2": case "R3": - decodeNetwork(position, fragments[4], false, true); + decodeNetwork(position, fragments[4], false, false, true); break; case "R12": case "R13": - decodeNetwork(position, fragments[4], true, true); + decodeNetwork(position, fragments[4], true, false, true); break; case "RH": decodeStatus(position, fragments[4]); break; + case "Y1": + decodeNetwork(position, fragments[4], true, true, false); + break; default: return null; } diff --git a/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java index 4c17bf1f8..ca8b67a46 100644 --- a/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MictrackProtocolDecoderTest extends ProtocolTest { var decoder = new MictrackProtocolDecoder(null); + verifyAttributes(decoder, text( + "MT;5;867035041396795;Y1;220111085741+test,8c:53:c3:db:e7:26,-58,jiuide-842,80:26:89:f0:5e:4f,-74,jiu2ide 403,94:e4:4b:0a:31:08,-75,jiu3ide,7a:91:e9:50:26:0b,-85,CNet-9rNe,78:91:e9:40:26:0b,-87+0+4092+1")); + verifyAttribute(decoder, text( "867035041390699 netlock=Success!"), Position.KEY_RESULT, "netlock=Success"); -- cgit v1.2.3 From 2284044f7e9e00935e6ec5020e68ef2492326dda Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Jan 2022 23:51:15 -0800 Subject: Decode location data --- .../traccar/protocol/OrbcommProtocolDecoder.java | 58 +++++++++++++++++++++- .../protocol/OrbcommProtocolDecoderTest.java | 5 +- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index daef923b0..d1e079711 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -19,15 +19,20 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpResponse; import org.traccar.BasePipelineFactory; import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; import org.traccar.Protocol; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; import javax.json.Json; +import javax.json.JsonArray; import javax.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.LinkedList; import java.util.TimeZone; public class OrbcommProtocolDecoder extends BaseProtocolDecoder { @@ -54,7 +59,58 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { } } - return null; + LinkedList positions = new LinkedList<>(); + + JsonArray messages = json.getJsonArray("Messages"); + for (int i = 0; i < messages.size(); i++) { + JsonObject message = messages.getJsonObject(i); + DeviceSession deviceSession = getDeviceSession( + channel, remoteAddress, true, message.getJsonNumber("ID").toString()); + if (deviceSession != null) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + position.setDeviceTime(dateFormat.parse(message.getString("MessageUTC"))); + + JsonArray fields = message.getJsonObject("Payload").getJsonArray("Fields"); + for (int j = 0; j < fields.size(); j++) { + JsonObject field = fields.getJsonObject(j); + String value = field.getString("Value"); + switch (field.getString("Name")) { + case "latitude": + position.setLatitude(Integer.parseInt(value) / 60000.0); + break; + case "longitude": + position.setLongitude(Integer.parseInt(value) / 60000.0); + break; + case "speed": + position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(value))); + break; + case "heading": + position.setCourse(Integer.parseInt(value) * 0.1); + break; + + default: + break; + } + } + + if (position.getLatitude() != 0 && position.getLongitude() != 0) { + position.setValid(true); + position.setFixTime(position.getDeviceTime()); + } else { + getLastLocation(position, position.getDeviceTime()); + } + + positions.add(position); + + } + } + + return positions.isEmpty() ? null : positions; } } diff --git a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java index 9cf841676..604ccef6e 100644 --- a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java @@ -10,7 +10,10 @@ public class OrbcommProtocolDecoderTest extends ProtocolTest { var decoder = new OrbcommProtocolDecoder(null); - verifyNull(decoder, response( + verifyPositions(decoder, response( + buffer("{\"ErrorID\":0,\"NextStartUTC\":\"2022-01-20 21:17:19\",\"Messages\":[{\"ID\":21545955455454,\"MessageUTC\":\"2022-01-20 21:17:19\",\"ReceiveUTC\":\"2022-01-20 21:17:19\",\"SIN\":19,\"MobileID\":\"01097623SKY2C68\",\"Payload\":{\"Name\":\"simpleReport\",\"SIN\":19,\"MIN\":1,\"Fields\":[{\"Name\":\"latitude\",\"Value\":\"2717900\",\"Type\":\"signedint\"},{\"Name\":\"longitude\",\"Value\":\"-4555211\",\"Type\":\"signedint\"},{\"Name\":\"speed\",\"Value\":\"0\",\"Type\":\"unsignedint\"},{\"Name\":\"heading\",\"Value\":\"1439\",\"Type\":\"unsignedint\"}]},\"RegionName\":\"\",\"OTAMessageSize\":17,\"CustomerID\":0,\"Transport\":1,\"MobileOwnerID\":60000934}]}"))); + + verifyPositions(decoder, false, response( buffer("{\"ErrorID\":0,\"NextStartUTC\":\"2016-10-13 15:19:59\",\"Messages\":[{\"ID\":120213064,\"MessageUTC\":\"2016-10-12 12:42:01\",\"ReceiveUTC\":\"2016-10-12 12:42:01\",\"SIN\":0,\"MobileID\":\"01173096SKY0E45\",\"Payload\":{\"Name\":\"modemRegistration\",\"SIN\":0,\"MIN\":0,\"Fields\":[{\"Name\":\"hardwareMajorVersion\",\"Value\":\"4\"},{\"Name\":\"hardwareMinorVersion\",\"Value\":\"2\"},{\"Name\":\"softwareMajorVersion\",\"Value\":\"13\"},{\"Name\":\"softwareMinorVersion\",\"Value\":\"1\"},{\"Name\":\"product\",\"Value\":\"4\"},{\"Name\":\"wakeupPeriod\",\"Value\":\"None\"},{\"Name\":\"lastResetReason\",\"Value\":\"Software\"},{\"Name\":\"virtualCarrier\",\"Value\":\"6\"},{\"Name\":\"beam\",\"Value\":\"1\"},{\"Name\":\"vain\",\"Value\":\"0\"},{\"Name\":\"reserved\",\"Value\":\"0\"},{\"Name\":\"operatorTxState\",\"Value\":\"0\"},{\"Name\":\"userTxState\",\"Value\":\"0\"},{\"Name\":\"broadcastIDCount\",\"Value\":\"0\"}],\"RegionName\":\"AMERRB11\",\"OTAMessageSize\":15,\"CustomerID\":0}}]}"))); } -- cgit v1.2.3 From cb07c34f3b79d82d85ab6c0df8f64c3c3facc3a0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 21 Jan 2022 18:59:49 -0800 Subject: Update Armoli protocol --- src/main/java/org/traccar/BaseProtocolPoller.java | 4 +-- .../java/org/traccar/protocol/ArmoliProtocol.java | 1 + .../traccar/protocol/ArmoliProtocolDecoder.java | 35 ++++++++++++++++++++-- .../org/traccar/protocol/ArmoliProtocolPoller.java | 35 ++++++++++++++++++++++ .../traccar/protocol/OrbcommProtocolPoller.java | 2 +- .../protocol/ArmoliProtocolDecoderTest.java | 8 +++++ 6 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java diff --git a/src/main/java/org/traccar/BaseProtocolPoller.java b/src/main/java/org/traccar/BaseProtocolPoller.java index 88138577c..5f4121fc1 100644 --- a/src/main/java/org/traccar/BaseProtocolPoller.java +++ b/src/main/java/org/traccar/BaseProtocolPoller.java @@ -29,8 +29,8 @@ public abstract class BaseProtocolPoller extends ChannelDuplexHandler { private final long interval; private Future timeout; - public BaseProtocolPoller(Protocol protocol) { - interval = Context.getConfig().getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol.getName())); + public BaseProtocolPoller(Protocol protocol, long interval) { + this.interval = interval; } protected abstract void sendRequest(Channel channel, SocketAddress remoteAddress); diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java index 1b8ce871c..7ee4289b0 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocol.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -32,6 +32,7 @@ public class ArmoliProtocol extends BaseProtocol { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new ArmoliProtocolDecoder(ArmoliProtocol.this)); + pipeline.addLast(new ArmoliProtocolPoller(ArmoliProtocol.this)); } }); } diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java index 46bdb484e..40beedbf6 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java @@ -50,6 +50,13 @@ public class ArmoliProtocolDecoder extends BaseProtocolDecoder { .number("(xx)") // status .number("(xx)") // max speed .number("(x{6})") // distance + .number("(dd)?") // hdop + .number("xx") // idle + .number(":(x+)").optional() // alarms + .number("G(x{6})").optional() // g-sensor + .number("H(x{3})").optional() // power + .number("E(x{3})").optional() // battery + .number("!(x+)").optional() // driver .any() .compile(); @@ -60,8 +67,14 @@ public class ArmoliProtocolDecoder extends BaseProtocolDecoder { String sentence = (String) msg; char type = sentence.charAt(1); + Position position = new Position(getProtocolName()); + if (type != 'M') { - if (channel != null && (type == 'Q' || type == 'L')) { + if (type == 'W') { + getLastLocation(position, null); + position.set(Position.KEY_RESULT, sentence.substring(sentence.indexOf(',') + 1, sentence.length() - 2)); + return position; + } else if (channel != null && (type == 'Q' || type == 'L')) { channel.writeAndFlush(new NetworkMessage("[TX,];;", remoteAddress)); } return null; @@ -77,7 +90,6 @@ public class ArmoliProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); @@ -96,6 +108,25 @@ public class ArmoliProtocolDecoder extends BaseProtocolDecoder { position.set("maxSpeed", parser.nextHexInt()); position.set(Position.KEY_ODOMETER, parser.nextHexInt()); + if (parser.hasNext()) { + position.set(Position.KEY_HDOP, parser.nextInt() * 0.1); + } + if (parser.hasNext()) { + position.set("alarms", parser.next()); + } + if (parser.hasNext()) { + position.set(Position.KEY_G_SENSOR, parser.next()); + } + if (parser.hasNext()) { + position.set(Position.KEY_POWER, parser.nextHexInt() * 0.01); + } + if (parser.hasNext()) { + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 0.01); + } + if (parser.hasNext()) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); + } + return position; } diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java b/src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java new file mode 100644 index 000000000..446ce8c39 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java @@ -0,0 +1,35 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.BaseProtocolPoller; +import org.traccar.Protocol; + +import java.net.SocketAddress; + +public class ArmoliProtocolPoller extends BaseProtocolPoller { + + public ArmoliProtocolPoller(Protocol protocol) { + super(protocol, 180000); + } + + @Override + protected void sendRequest(Channel channel, SocketAddress remoteAddress) { + channel.writeAndFlush("[TX,];;"); + } + +} diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java index bf1093654..65e98474b 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java @@ -47,7 +47,7 @@ public class OrbcommProtocolPoller extends BaseProtocolPoller { } public OrbcommProtocolPoller(Protocol protocol) { - super(protocol); + super(protocol, Context.getConfig().getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol.getName()))); accessId = Context.getConfig().getString(Keys.ORBCOMM_ACCESS_ID); password = Context.getConfig().getString(Keys.ORBCOMM_PASSWORD); host = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol.getName())); diff --git a/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java index 0851b1e05..9b5aa4125 100644 --- a/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class ArmoliProtocolDecoderTest extends ProtocolTest { @@ -10,6 +11,13 @@ public class ArmoliProtocolDecoderTest extends ProtocolTest { var decoder = new ArmoliProtocolDecoder(null); + verifyAttribute(decoder, text( + "[W869867038698074,O,1234,2657,1];"), + Position.KEY_RESULT, "O,1234,2657,1"); + + verifyPosition(decoder, text( + "[M869867038698074210122125205N38.735641E035.4727751E003340000000C00000E9E07FF:106AG505283H60E];")); + verifyNull(decoder, text( "[Q010001088610010024363698990011101070608200,05XXXXXXXXX,10.49.182.53,C,1,20,19,0];")); -- cgit v1.2.3 From 96c3589154583f57e5aa39663679fc5df103f394 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 21 Jan 2022 19:01:42 -0800 Subject: Fix style issues --- src/main/java/org/traccar/BaseProtocolPoller.java | 3 +-- src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java | 2 +- src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/BaseProtocolPoller.java b/src/main/java/org/traccar/BaseProtocolPoller.java index 5f4121fc1..be6556374 100644 --- a/src/main/java/org/traccar/BaseProtocolPoller.java +++ b/src/main/java/org/traccar/BaseProtocolPoller.java @@ -19,7 +19,6 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.util.concurrent.Future; -import org.traccar.config.Keys; import java.net.SocketAddress; import java.util.concurrent.TimeUnit; @@ -29,7 +28,7 @@ public abstract class BaseProtocolPoller extends ChannelDuplexHandler { private final long interval; private Future timeout; - public BaseProtocolPoller(Protocol protocol, long interval) { + public BaseProtocolPoller(long interval) { this.interval = interval; } diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java b/src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java index 446ce8c39..f7bb9f593 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolPoller.java @@ -24,7 +24,7 @@ import java.net.SocketAddress; public class ArmoliProtocolPoller extends BaseProtocolPoller { public ArmoliProtocolPoller(Protocol protocol) { - super(protocol, 180000); + super(180000); } @Override diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java index 65e98474b..6a2d7a92d 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java @@ -47,7 +47,7 @@ public class OrbcommProtocolPoller extends BaseProtocolPoller { } public OrbcommProtocolPoller(Protocol protocol) { - super(protocol, Context.getConfig().getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol.getName()))); + super(Context.getConfig().getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol.getName()))); accessId = Context.getConfig().getString(Keys.ORBCOMM_ACCESS_ID); password = Context.getConfig().getString(Keys.ORBCOMM_PASSWORD); host = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol.getName())); -- cgit v1.2.3 From 865e3c41122a07c6e752b299b0d687330b22ebda Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Jan 2022 09:51:19 -0800 Subject: Set device id --- .../java/org/traccar/protocol/ArmoliProtocolDecoder.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java index 40beedbf6..b1140d79c 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java @@ -68,12 +68,19 @@ public class ArmoliProtocolDecoder extends BaseProtocolDecoder { char type = sentence.charAt(1); Position position = new Position(getProtocolName()); + DeviceSession deviceSession; if (type != 'M') { if (type == 'W') { - getLastLocation(position, null); - position.set(Position.KEY_RESULT, sentence.substring(sentence.indexOf(',') + 1, sentence.length() - 2)); - return position; + deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + getLastLocation(position, null); + position.set( + Position.KEY_RESULT, + sentence.substring(sentence.indexOf(',') + 1, sentence.length() - 2)); + return position; + } } else if (channel != null && (type == 'Q' || type == 'L')) { channel.writeAndFlush(new NetworkMessage("[TX,];;", remoteAddress)); } @@ -85,7 +92,7 @@ public class ArmoliProtocolDecoder extends BaseProtocolDecoder { return null; } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } -- cgit v1.2.3 From b918660950f459959c3a975c558448c907d6a3b4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Jan 2022 09:53:55 -0800 Subject: Fix test case --- src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java index 9b5aa4125..d3269e7d3 100644 --- a/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java @@ -11,13 +11,13 @@ public class ArmoliProtocolDecoderTest extends ProtocolTest { var decoder = new ArmoliProtocolDecoder(null); - verifyAttribute(decoder, text( - "[W869867038698074,O,1234,2657,1];"), - Position.KEY_RESULT, "O,1234,2657,1"); - verifyPosition(decoder, text( "[M869867038698074210122125205N38.735641E035.4727751E003340000000C00000E9E07FF:106AG505283H60E];")); + verifyAttribute(decoder, text( + "[W869867038698074,O,1234,2657,1];"), + Position.KEY_RESULT, "O,1234,2657,1"); + verifyNull(decoder, text( "[Q010001088610010024363698990011101070608200,05XXXXXXXXX,10.49.182.53,C,1,20,19,0];")); -- cgit v1.2.3 From a8af4b7d0b7eec1e3076bd51bc2e81c6df0626ac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Jan 2022 18:27:02 -0800 Subject: Update Armoli frame decoder --- src/main/java/org/traccar/protocol/ArmoliProtocol.java | 2 +- src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java | 2 +- .../java/org/traccar/protocol/ArmoliProtocolDecoderTest.java | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java index 7ee4289b0..dec8c6fe0 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocol.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -28,7 +28,7 @@ public class ArmoliProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";\r", ";")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new ArmoliProtocolDecoder(ArmoliProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java index b1140d79c..400e4ad89 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java @@ -78,7 +78,7 @@ public class ArmoliProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); position.set( Position.KEY_RESULT, - sentence.substring(sentence.indexOf(',') + 1, sentence.length() - 2)); + sentence.substring(sentence.indexOf(',') + 1, sentence.length() - 1)); return position; } } else if (channel != null && (type == 'Q' || type == 'L')) { diff --git a/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java index d3269e7d3..c64fbd411 100644 --- a/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java @@ -12,20 +12,20 @@ public class ArmoliProtocolDecoderTest extends ProtocolTest { var decoder = new ArmoliProtocolDecoder(null); verifyPosition(decoder, text( - "[M869867038698074210122125205N38.735641E035.4727751E003340000000C00000E9E07FF:106AG505283H60E];")); + "[M869867038698074210122125205N38.735641E035.4727751E003340000000C00000E9E07FF:106AG505283H60E]")); verifyAttribute(decoder, text( - "[W869867038698074,O,1234,2657,1];"), + "[W869867038698074,O,1234,2657,1]"), Position.KEY_RESULT, "O,1234,2657,1"); verifyNull(decoder, text( - "[Q010001088610010024363698990011101070608200,05XXXXXXXXX,10.49.182.53,C,1,20,19,0];")); + "[Q010001088610010024363698990011101070608200,05XXXXXXXXX,10.49.182.53,C,1,20,19,0]")); verifyPosition(decoder, text( - "[M860906041293587100122061310N40.792751E029.4313092801143000000010003513209FFGC18080H8DA#E209C4];")); + "[M860906041293587100122061310N40.792751E029.4313092801143000000010003513209FFGC18080H8DA#E209C4]")); verifyNull(decoder, text( - "[L866104027971681];")); + "[L866104027971681]")); } -- cgit v1.2.3 From 5a854ce946cc49dbb176b5a436a1b1d6673ba096 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 24 Jan 2022 20:18:57 -0800 Subject: Handle empty response --- src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java | 7 ++++++- src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index d1e079711..aff722c46 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -27,6 +27,7 @@ import org.traccar.model.Position; import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.json.JsonValue; import java.io.StringReader; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; @@ -49,7 +50,7 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { String content = response.content().toString(StandardCharsets.UTF_8); JsonObject json = Json.createReader(new StringReader(content)).readObject(); - if (channel != null) { + if (channel != null && !json.getString("NextStartUTC").isEmpty()) { OrbcommProtocolPoller poller = BasePipelineFactory.getHandler(channel.pipeline(), OrbcommProtocolPoller.class); if (poller != null) { @@ -59,6 +60,10 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { } } + if (json.get("Messages").getValueType() == JsonValue.ValueType.NULL) { + return null; + } + LinkedList positions = new LinkedList<>(); JsonArray messages = json.getJsonArray("Messages"); diff --git a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java index 604ccef6e..af35505d5 100644 --- a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class OrbcommProtocolDecoderTest extends ProtocolTest { var decoder = new OrbcommProtocolDecoder(null); + verifyNull(decoder, response( + buffer("{\"ErrorID\":0,\"NextStartUTC\":\"\",\"Messages\":null}"))); + verifyPositions(decoder, response( buffer("{\"ErrorID\":0,\"NextStartUTC\":\"2022-01-20 21:17:19\",\"Messages\":[{\"ID\":21545955455454,\"MessageUTC\":\"2022-01-20 21:17:19\",\"ReceiveUTC\":\"2022-01-20 21:17:19\",\"SIN\":19,\"MobileID\":\"01097623SKY2C68\",\"Payload\":{\"Name\":\"simpleReport\",\"SIN\":19,\"MIN\":1,\"Fields\":[{\"Name\":\"latitude\",\"Value\":\"2717900\",\"Type\":\"signedint\"},{\"Name\":\"longitude\",\"Value\":\"-4555211\",\"Type\":\"signedint\"},{\"Name\":\"speed\",\"Value\":\"0\",\"Type\":\"unsignedint\"},{\"Name\":\"heading\",\"Value\":\"1439\",\"Type\":\"unsignedint\"}]},\"RegionName\":\"\",\"OTAMessageSize\":17,\"CustomerID\":0,\"Transport\":1,\"MobileOwnerID\":60000934}]}"))); -- cgit v1.2.3 From fd536f9e0dd33807a3638a0a134dfd97f18a096c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 24 Jan 2022 22:13:47 -0800 Subject: Fix DSF22 decoding --- .../java/org/traccar/protocol/Dsf22ProtocolDecoder.java | 13 ++++++------- .../java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java | 5 +++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java index d5a9df7bc..3ef960f12 100644 --- a/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@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,7 +16,6 @@ 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; @@ -46,7 +45,7 @@ public class Dsf22ProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(2); // header - String id = ByteBufUtil.hexDump(buf.readSlice(2)); + String id = String.valueOf(buf.readUnsignedShortLE()); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession == null) { return null; @@ -61,12 +60,12 @@ public class Dsf22ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.setValid(true); - position.setLatitude(buf.readInt()); - position.setLongitude(buf.readInt()); - position.setTime(new Date(946684800000L + buf.readUnsignedInt())); + position.setLatitude(buf.readIntLE() / 10000000.0); + position.setLongitude(buf.readIntLE() / 10000000.0); + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShortLE() * 0.001); int status = buf.readUnsignedByte(); position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); diff --git a/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java index 96cd78f03..4089c208c 100644 --- a/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java @@ -1,10 +1,8 @@ package org.traccar.protocol; -import org.junit.Ignore; import org.junit.Test; import org.traccar.ProtocolTest; -@Ignore public class Dsf22ProtocolDecoderTest extends ProtocolTest { @Test @@ -12,6 +10,9 @@ public class Dsf22ProtocolDecoderTest extends ProtocolTest { var decoder = new Dsf22ProtocolDecoder(null); + verifyPositions(decoder, binary( + "4642a82d01c8f6aa1af1792c0c1411eb61001e0000")); + verifyPositions(decoder, binary( "4642000101A8EE5F0ECA5FF421B33F524E32610401")); -- cgit v1.2.3 From afee330248c3e39029102ab984382ae9723895ae Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 24 Jan 2022 22:16:42 -0800 Subject: Armoli frame decoder update --- src/main/java/org/traccar/protocol/ArmoliProtocol.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java index dec8c6fe0..5f36012af 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocol.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -28,7 +28,7 @@ public class ArmoliProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";\r", ";")); + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";;", ";\r", ";")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new ArmoliProtocolDecoder(ArmoliProtocol.this)); -- cgit v1.2.3 From 955d19a1d4937f1650cbcc94731701b4637721f4 Mon Sep 17 00:00:00 2001 From: l-e-o-n-c-e <38976766+l-e-o-n-c-e@users.noreply.github.com> Date: Wed, 26 Jan 2022 21:29:23 +0100 Subject: Add an alarm code on Watch protocol Some 2G devices send a 00004000 code when the device is removed from its charger. This is very useful as many cheap devices have a strange magnet connector which is very easy to unplug by accident. If not working, the feature might have to be activated by sending AON,1# to the device. Does NOT work on 4G devices which send a "sos" alert in that situation (00010000). --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 4990cfd65..527a21e7c 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -89,6 +89,8 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_GEOFENCE_EXIT; } else if (BitUtil.check(status, 2)) { return Position.ALARM_GEOFENCE_ENTER; + } else if (BitUtil.check(status, 14)) { + return Position.ALARM_POWER_CUT; // some 2G devices raise this alarm when the device is unplugged from its charger } else if (BitUtil.check(status, 16)) { return Position.ALARM_SOS; } else if (BitUtil.check(status, 17)) { -- cgit v1.2.3 From 4b43eee0a571ea9d62854cdeb0891166c103bb7d Mon Sep 17 00:00:00 2001 From: l-e-o-n-c-e <38976766+l-e-o-n-c-e@users.noreply.github.com> Date: Wed, 26 Jan 2022 21:38:58 +0100 Subject: Update WatchProtocolDecoder.java --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 527a21e7c..557832f05 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -90,7 +90,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { } else if (BitUtil.check(status, 2)) { return Position.ALARM_GEOFENCE_ENTER; } else if (BitUtil.check(status, 14)) { - return Position.ALARM_POWER_CUT; // some 2G devices raise this alarm when the device is unplugged from its charger + return Position.ALARM_POWER_CUT; // raised by some 2G devices when unplugged from their charger } else if (BitUtil.check(status, 16)) { return Position.ALARM_SOS; } else if (BitUtil.check(status, 17)) { -- cgit v1.2.3 From b77326b34401d8df3674d4de1e3efd44dde7081b Mon Sep 17 00:00:00 2001 From: l-e-o-n-c-e <38976766+l-e-o-n-c-e@users.noreply.github.com> Date: Wed, 26 Jan 2022 21:45:44 +0100 Subject: Update WatchProtocolDecoder.java Removed the comment as requested by Anton (but I found it useful since the status "POWER_CUT"I used could be confusing imo) --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 557832f05..cf58b0fed 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -90,7 +90,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { } else if (BitUtil.check(status, 2)) { return Position.ALARM_GEOFENCE_ENTER; } else if (BitUtil.check(status, 14)) { - return Position.ALARM_POWER_CUT; // raised by some 2G devices when unplugged from their charger + return Position.ALARM_POWER_CUT; } else if (BitUtil.check(status, 16)) { return Position.ALARM_SOS; } else if (BitUtil.check(status, 17)) { -- cgit v1.2.3 From decc6d4c592b9511fda3db943f43e4a6d29841f0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 26 Jan 2022 19:43:49 -0800 Subject: Support Lanyard device --- src/main/java/org/traccar/protocol/S168ProtocolDecoder.java | 5 ++++- src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java index 71aff1a65..685364483 100644 --- a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@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,6 +51,9 @@ public class S168ProtocolDecoder extends BaseProtocolDecoder { String content = values[4]; String[] fragments = content.split(";"); for (String fragment : fragments) { + if (fragment.isEmpty()) { + continue; + } int dataIndex = fragment.indexOf(':'); String type = fragment.substring(0, dataIndex); diff --git a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java index d4918e121..6bdf19182 100644 --- a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class S168ProtocolDecoderTest extends ProtocolTest { var decoder = new S168ProtocolDecoder(null); + verifyPosition(decoder, text( + "S168#358511039001705#003a#01ca#LOCA:G;CELL:6,1cc,0,2479,de11150,2e,2479,d6e4546,31,2479,d6e4547,39,778c,787cc30,39,778c,787cc31,40,253f,6195502,32;GDATA:A,5,220117220950,22.779583,113.820633,5,296,35;ALERT:0080;STATUS:98,73;;FARM:0,0009,0000,010a,20220117220950;WIFI:10,CC-08-FB-A5-49-B3,-28,08-40-F3-7F-6C-A9,-59,A4-29-40-65-2C-42,-74,80-89-17-A5-6F-7B,-82,80-EA-07-82-93-C6,-82,FC-37-2B-34-D6-A1,-83,34-6B-5B-A9-49-15,-83,BC-46-99-B3-51-10,-84,BC-54-FC-53-0A-D1,-84,3C-CD-57-67-D1-32,-85")); + verifyNull(decoder, text( "S168#358511139046180#00c9#0009#SYNC:0000")); -- cgit v1.2.3 From c45b4d8d1e29227937afa9114ead5ae16f548aa0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 27 Jan 2022 18:26:29 -0800 Subject: Support Armoli OBD data --- .../java/org/traccar/protocol/ArmoliProtocolDecoder.java | 13 ++++++++++++- .../org/traccar/protocol/ArmoliProtocolDecoderTest.java | 6 +++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java index 400e4ad89..50af039d6 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java @@ -20,6 +20,7 @@ import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; +import org.traccar.helper.ObdDecoder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -51,12 +52,13 @@ public class ArmoliProtocolDecoder extends BaseProtocolDecoder { .number("(xx)") // max speed .number("(x{6})") // distance .number("(dd)?") // hdop - .number("xx") // idle + .number("x{4}") // idle .number(":(x+)").optional() // alarms .number("G(x{6})").optional() // g-sensor .number("H(x{3})").optional() // power .number("E(x{3})").optional() // battery .number("!(x+)").optional() // driver + .expression("@A([>0-9A-F]+)").optional() // obd .any() .compile(); @@ -133,6 +135,15 @@ public class ArmoliProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); } + if (parser.hasNext()) { + String[] values = parser.next().split(">"); + for (int i = 1; i < values.length; i++) { + String value = values[i]; + position.add(ObdDecoder.decodeData( + Integer.parseInt(value.substring(4, 6), 16), + Long.parseLong(value.substring(6), 16), true)); + } + } return position; } diff --git a/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java index c64fbd411..da2542b34 100644 --- a/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ArmoliProtocolDecoderTest.java @@ -11,11 +11,15 @@ public class ArmoliProtocolDecoderTest extends ProtocolTest { var decoder = new ArmoliProtocolDecoder(null); + verifyAttribute(decoder, text( + "[M869867039550712160821153237N41.033508E029.2697032F00036000000410006B336FFFFG458563@A6D>04410C2482>03410F56>03412F19>0441210000>034130FF>0441313A7>03410D30>04411F01B6>0341048C>04410C1C98];"), + Position.KEY_RPM, 1830L); + verifyPosition(decoder, text( "[M869867038698074210122125205N38.735641E035.4727751E003340000000C00000E9E07FF:106AG505283H60E]")); verifyAttribute(decoder, text( - "[W869867038698074,O,1234,2657,1]"), + "[W869867038698074,O,1234,2657,1]"), Position.KEY_RESULT, "O,1234,2657,1"); verifyNull(decoder, text( -- cgit v1.2.3 From ff51e1ecafe3b26929baa21a20583c1e8ac82271 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 28 Jan 2022 11:08:27 -0800 Subject: Another H02 coordinates format --- .../org/traccar/protocol/H02ProtocolDecoder.java | 34 +++++++++++++--------- .../traccar/protocol/H02ProtocolDecoderTest.java | 3 ++ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java index dd7141a2c..10a272bff 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -176,17 +176,19 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // coding scheme .groupEnd() .groupBegin() - .number("-(d+)-(d+.d+),") // latitude + .number("-(d+)-(d+.d+),([NS]),") // latitude .or() - .number("(d+)(dd.d+),") // latitude + .number("(d+)(dd.d+),([NS]),") // latitude + .or() + .number("(d+)(dd)(d{4}),([NS]),") // latitude .groupEnd() - .expression("([NS]),") .groupBegin() - .number("-(d+)-(d+.d+),") // longitude + .number("-(d+)-(d+.d+),([EW]),") // longitude .or() - .number("(d+)(dd.d+),") // longitude + .number("(d+)(dd.d+),([EW]),") // longitude + .or() + .number("(d+)(dd)(d{4}),([EW]),") // longitude .groupEnd() - .expression("([EW]),") .number(" *(d+.?d*),") // speed .number("(d+.?d*)?,") // course .number("(?:d+,)?") // battery @@ -349,19 +351,25 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.setValid(true); } - if (parser.hasNext(2)) { - position.setLatitude(-parser.nextCoordinate()); + if (parser.hasNext(3)) { + position.setLatitude(parser.nextCoordinate()); } - if (parser.hasNext(2)) { + if (parser.hasNext(3)) { position.setLatitude(parser.nextCoordinate()); } + if (parser.hasNext(4)) { + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); + } - if (parser.hasNext(2)) { - position.setLongitude(-parser.nextCoordinate()); + if (parser.hasNext(3)) { + position.setLongitude(parser.nextCoordinate()); } - if (parser.hasNext(2)) { + if (parser.hasNext(3)) { position.setLongitude(parser.nextCoordinate()); } + if (parser.hasNext(4)) { + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); + } position.setSpeed(parser.nextDouble(0)); position.setCourse(parser.nextDouble(0)); diff --git a/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java index a0462e675..ad5f82176 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 { var decoder = new H02ProtocolDecoder(null); + verifyPosition(decoder, buffer( + "*HQ,5905101893,V1,105759,A,37573392,S,145037022,E,000.00,173,280122,FF7FFBFF,,,9059e2c,8232,4#")); + verifyPosition(decoder, buffer( "*HQ,4970105243,V1,104000,A,2235.1777,N,11357.8913,E,000.27,235,130721,FFFFFBFF,460,11,d18e105,7752,6#")); -- cgit v1.2.3 From 17a9b88676b1cef214f1944e39151c7df8f4e3b0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 30 Jan 2022 11:50:17 -0800 Subject: Add crash reconstruction report --- .../traccar/protocol/SuntechProtocolDecoder.java | 97 +++++++++++++++++++++- .../protocol/SuntechProtocolDecoderTest.java | 13 +++ 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 2d00ea81e..9d832c84e 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@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.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; @@ -34,6 +35,11 @@ import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; import java.util.TimeZone; public class SuntechProtocolDecoder extends BaseProtocolDecoder { @@ -46,6 +52,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { private boolean includeRpm; private boolean includeTemp; + private ByteBuf crash; + public SuntechProtocolDecoder(Protocol protocol) { super(protocol); } @@ -732,6 +740,89 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return position; } + private Collection decodeCrashReport(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + + if (buf.getByte(buf.readerIndex() + 3) != ';') { + return null; + } + + String[] values = buf.readCharSequence(23, StandardCharsets.US_ASCII).toString().split(";"); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[1]); + if (deviceSession == null) { + return null; + } + + int currentIndex = Integer.parseInt(values[2]); + int totalIndex = Integer.parseInt(values[3]); + + if (crash == null) { + crash = Unpooled.buffer(); + } + + crash.writeBytes(buf.readSlice(buf.readableBytes() - 3)); + + if (currentIndex == totalIndex) { + + LinkedList positions = new LinkedList<>(); + + Date crashTime = new DateBuilder() + .setDate(crash.readUnsignedByte(), crash.readUnsignedByte(), crash.readUnsignedByte()) + .setTime(crash.readUnsignedByte(), crash.readUnsignedByte(), crash.readUnsignedByte()) + .getDate(); + + List times = Arrays.asList( + new Date(crashTime.getTime() - 3000), + new Date(crashTime.getTime() - 2000), + new Date(crashTime.getTime() - 1000), + new Date(crashTime.getTime() + 1000)); + + for (Date time : times) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setTime(time); + position.setLatitude(crash.readIntLE() * 0.0000001); + position.setLongitude(crash.readIntLE() * 0.0000001); + position.setSpeed(UnitsConverter.knotsFromKph(crash.readUnsignedShort() * 0.01)); + position.setCourse(crash.readUnsignedShort() * 0.01); + + StringBuilder value = new StringBuilder("["); + for (int i = 0; i < 100; i++){ + if (value.length() > 1) { + value.append(","); + } + value.append("["); + value.append(crash.readShortLE()); + value.append(","); + value.append(crash.readShortLE()); + value.append(","); + value.append(crash.readShortLE()); + value.append("]"); + } + value.append("]"); + + position.set(Position.KEY_G_SENSOR, value.toString()); + + positions.add(position); + + } + + crash.release(); + crash = null; + + return positions; + + } else { + + return null; + + } + + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -747,7 +838,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { String[] values = buf.toString(StandardCharsets.US_ASCII).split(";"); prefix = values[0]; - if (prefix.length() < 5) { + if (prefix.equals("CRR")) { + return decodeCrashReport(channel, remoteAddress, buf); + } else if (prefix.length() < 5) { return decodeUniversal(channel, remoteAddress, values); } else if (prefix.endsWith("HTE")) { return decodeTravelReport(channel, remoteAddress, values); diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index a9720f437..098758728 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -1,5 +1,6 @@ package org.traccar.protocol; +import org.junit.Ignore; import org.junit.Test; import org.traccar.ProtocolTest; import org.traccar.model.Position; @@ -257,4 +258,16 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { } + @Ignore + @Test + public void testDecodeCrash() throws Exception { + + var decoder = new SuntechProtocolDecoder(null); + + verifyAttribute(decoder, binary( + "4352523b303931303030303036333b313b313b303135303b16011c150f0ad82f6c0000000000ae037085fbff7700fd00faff6300f30000006800fb000d007100fa00f32f6c00000000005e044a80fcff6f000301e1ff5d00e900e1ff6400e600f4ff5b00ec000a306c00000000002104248306006c000501fcff5b00e00001006e000101eeff4e00e10022306c00000000005c041a7e00006a00010100005d00f800b5ff7cffdf0050009300fc003b44350d"), + Position.KEY_G_SENSOR, ""); + + } + } -- cgit v1.2.3 From b332952f24a8b162b61024622771fb1dab41f9a3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 30 Jan 2022 11:57:38 -0800 Subject: Fix code style --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 9d832c84e..2f8e50c5e 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -790,7 +790,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setCourse(crash.readUnsignedShort() * 0.01); StringBuilder value = new StringBuilder("["); - for (int i = 0; i < 100; i++){ + for (int i = 0; i < 100; i++) { if (value.length() > 1) { value.append(","); } -- cgit v1.2.3 From 2dd9cf55d1503aa4a35fd0b57126435e4036a9ff Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 31 Jan 2022 18:11:05 -0800 Subject: Add Geoapify geocoder --- src/main/java/org/traccar/MainModule.java | 5 +- .../org/traccar/geocoder/GeoapifyGeocoder.java | 81 ++++++++++++++++++++++ .../java/org/traccar/geocoder/GeocoderTest.java | 10 ++- 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 11100f66e..aaa82adfc 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@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,6 +34,7 @@ import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; import org.traccar.geocoder.BingMapsGeocoder; import org.traccar.geocoder.FactualGeocoder; +import org.traccar.geocoder.GeoapifyGeocoder; import org.traccar.geocoder.GeocodeFarmGeocoder; import org.traccar.geocoder.GeocodeXyzGeocoder; import org.traccar.geocoder.Geocoder; @@ -197,6 +198,8 @@ public class MainModule extends AbstractModule { return new MapboxGeocoder(key, cacheSize, addressFormat); case "maptiler": return new MapTilerGeocoder(key, cacheSize, addressFormat); + case "geoapify": + return new GeoapifyGeocoder(key, language, cacheSize, addressFormat); default: return new GoogleGeocoder(key, language, cacheSize, addressFormat); } diff --git a/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java b/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java new file mode 100644 index 000000000..ef0e4c8bd --- /dev/null +++ b/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java @@ -0,0 +1,81 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.geocoder; + +import javax.json.JsonArray; +import javax.json.JsonObject; + +public class GeoapifyGeocoder extends JsonGeocoder { + + private static String formatUrl(String key, String language) { + String url = "https://api.geoapify.com/v1/geocode/reverse?format=json&lat=%f&lon=%f"; + if (key != null) { + url += "&apiKey=" + key; + } + if (language != null) { + url += "&lang=" + language; + } + return url; + } + + public GeoapifyGeocoder(String key, String language, int cacheSize, AddressFormat addressFormat) { + super(formatUrl(key, language), cacheSize, addressFormat); + } + + @Override + public Address parseAddress(JsonObject json) { + JsonArray results = json.getJsonArray("results"); + if (results.size() > 0) { + JsonObject result = results.getJsonObject(0); + + Address address = new Address(); + + if (json.containsKey("formatted")) { + address.setFormattedAddress(json.getString("formatted")); + } + + if (result.containsKey("housenumber")) { + address.setHouse(result.getString("housenumber")); + } + if (result.containsKey("street")) { + address.setStreet(result.getString("street")); + } + if (result.containsKey("suburb")) { + address.setSuburb(result.getString("suburb")); + } + if (result.containsKey("city")) { + address.setSettlement(result.getString("city")); + } + if (result.containsKey("district")) { + address.setDistrict(result.getString("district")); + } + if (result.containsKey("state")) { + address.setState(result.getString("state")); + } + if (result.containsKey("country_code")) { + address.setCountry(result.getString("country_code").toUpperCase()); + } + if (result.containsKey("postcode")) { + address.setPostcode(result.getString("postcode")); + } + + return address; + } + + return null; + } + +} diff --git a/src/test/java/org/traccar/geocoder/GeocoderTest.java b/src/test/java/org/traccar/geocoder/GeocoderTest.java index 380980d2b..9134194f2 100644 --- a/src/test/java/org/traccar/geocoder/GeocoderTest.java +++ b/src/test/java/org/traccar/geocoder/GeocoderTest.java @@ -105,9 +105,17 @@ public class GeocoderTest { @Ignore @Test public void testMapTiler() { - Geocoder geocoder = new MapTilerGeocoder("mnbnwLErpdspq13f0kC6", 0, new AddressFormat()); + Geocoder geocoder = new MapTilerGeocoder("", 0, new AddressFormat()); String address = geocoder.getAddress(40.733, -73.989, null); assertEquals("East 13th Street, New York City, New York, United States", address); } + @Ignore + @Test + public void testGeoapify() { + Geocoder geocoder = new GeoapifyGeocoder("", null, 0, new AddressFormat()); + String address = geocoder.getAddress(40.733, -73.989, null); + assertEquals("114 East 13th Street, New York, New York, US", address); + } + } -- cgit v1.2.3 From 9acf9c7f7a4c3d8279b0afb9683098984a1b4518 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 31 Jan 2022 22:57:36 -0800 Subject: Add option to disable reports --- schema/changelog-4.16.xml | 21 +++++++++++++++++++++ schema/changelog-master.xml | 1 + .../org/traccar/api/resource/PositionResource.java | 3 ++- .../org/traccar/api/resource/ReportResource.java | 12 +++++++++++- .../org/traccar/database/PermissionsManager.java | 16 ++++++++++++++-- src/main/java/org/traccar/model/Server.java | 12 +++++++++++- src/main/java/org/traccar/model/User.java | 10 ++++++++++ 7 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 schema/changelog-4.16.xml diff --git a/schema/changelog-4.16.xml b/schema/changelog-4.16.xml new file mode 100644 index 000000000..0b6493f03 --- /dev/null +++ b/schema/changelog-4.16.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index 245367de3..354037cdd 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -29,5 +29,6 @@ + diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 998d59706..53157197b 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,6 +55,7 @@ public class PositionResource extends BaseResource { } else { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); if (from != null && to != null) { + Context.getPermissionsManager().checkDisableReports(getUserId()); return Context.getDataManager().getPositions(deviceId, from, to); } else { return Collections.singleton(Context.getDeviceManager().getLastPosition(deviceId)); diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 7347bfd64..23ffaf54c 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -99,6 +99,7 @@ public class ReportResource extends BaseResource { public Collection getRoute( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws SQLException { + Context.getPermissionsManager().checkDisableReports(getUserId()); LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); return Route.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -110,6 +111,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws SQLException, IOException { + Context.getPermissionsManager().checkDisableReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); Route.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); @@ -122,6 +124,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to) throws SQLException { + Context.getPermissionsManager().checkDisableReports(getUserId()); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); return Events.getObjects(getUserId(), deviceIds, groupIds, types, from, to); } @@ -134,6 +137,7 @@ public class ReportResource extends BaseResource { @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws SQLException, IOException { + Context.getPermissionsManager().checkDisableReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); Events.getExcel(stream, getUserId(), deviceIds, groupIds, types, from, to); @@ -146,6 +150,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily) throws SQLException { + Context.getPermissionsManager().checkDisableReports(getUserId()); LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); return Summary.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); } @@ -158,6 +163,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily, @QueryParam("mail") boolean mail) throws SQLException, IOException { + Context.getPermissionsManager().checkDisableReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); Summary.getExcel(stream, getUserId(), deviceIds, groupIds, from, to, daily); @@ -170,6 +176,7 @@ public class ReportResource extends BaseResource { public Collection getTrips( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws SQLException { + Context.getPermissionsManager().checkDisableReports(getUserId()); LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); return Trips.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -181,6 +188,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws SQLException, IOException { + Context.getPermissionsManager().checkDisableReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); Trips.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); @@ -193,6 +201,7 @@ public class ReportResource extends BaseResource { public Collection getStops( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws SQLException { + Context.getPermissionsManager().checkDisableReports(getUserId()); LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); return Stops.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -204,6 +213,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws SQLException, IOException { + Context.getPermissionsManager().checkDisableReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); Stops.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 32464cf90..ab841a521 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -274,6 +274,11 @@ public class PermissionsManager { return user != null && user.getLimitCommands(); } + public boolean getUserDisableReport(long userId) { + User user = getUser(userId); + return user != null && user.getDisableReports(); + } + public void checkReadonly(long userId) throws SecurityException { if (!getUserAdmin(userId) && (server.getReadonly() || getUserReadonly(userId))) { throw new SecurityException("Account is readonly"); @@ -292,6 +297,12 @@ public class PermissionsManager { } } + public void checkDisableReports(long userId) throws SecurityException { + if (!getUserAdmin(userId) && (server.getDisableReports() || getUserDisableReport(userId))) { + throw new SecurityException("Account has reports disabled"); + } + } + public void checkUserDeviceCommand(long userId, long deviceId, long commandId) throws SecurityException { if (!getUserAdmin(userId) && Context.getCommandsManager().checkDeviceCommand(deviceId, commandId)) { throw new SecurityException("Command can not be sent to this device"); @@ -326,7 +337,8 @@ public class PermissionsManager { if (before.getReadonly() != after.getReadonly() || before.getDeviceReadonly() != after.getDeviceReadonly() || before.getDisabled() != after.getDisabled() - || before.getLimitCommands() != after.getLimitCommands()) { + || before.getLimitCommands() != after.getLimitCommands() + || before.getDisableReports() != after.getDisableReports()) { if (userId == after.getId()) { checkAdmin(userId); } diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index 7bdb53b22..03d087cac 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -152,6 +152,16 @@ public class Server extends ExtendedModel { this.limitCommands = limitCommands; } + private boolean disableReports; + + public boolean getDisableReports() { + return disableReports; + } + + public void setDisableReports(boolean disableReports) { + this.disableReports = disableReports; + } + private String poiLayer; public String getPoiLayer() { diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 976b6aac0..359bdc2c2 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -224,6 +224,16 @@ public class User extends ExtendedModel { private String poiLayer; + private boolean disableReports; + + public boolean getDisableReports() { + return disableReports; + } + + public void setDisableReports(boolean disableReports) { + this.disableReports = disableReports; + } + public String getPoiLayer() { return poiLayer; } -- cgit v1.2.3 From 3a045b29bfc8a0b3a65db3ccc973dcbd5901c1e5 Mon Sep 17 00:00:00 2001 From: jafarhabibi Date: Tue, 1 Feb 2022 11:56:40 +0330 Subject: add skiplimit and skipAttributes checks for Duplicate filter again --- src/main/java/org/traccar/handler/FilterHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 049512765..2b850c755 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -181,7 +181,7 @@ public class FilterHandler extends BaseDataHandler { } else { preceding = getLastReceivedPosition(deviceId); } - if (filterDuplicate(position, preceding)) { + if (filterDuplicate(position, preceding) && !skipLimit(position, preceding) && !skipAttributes(position)) { filterType.append("Duplicate "); } if (filterStatic(position) && !skipLimit(position, preceding) && !skipAttributes(position)) { -- cgit v1.2.3 From 0738af216e7b31926e05d3de64e14e5b7f0b214c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Feb 2022 23:55:53 -0800 Subject: Fix buffer search --- src/main/java/org/traccar/helper/BufferUtil.java | 4 +-- .../java/org/traccar/helper/BufferUtilTest.java | 35 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/traccar/helper/BufferUtilTest.java diff --git a/src/main/java/org/traccar/helper/BufferUtil.java b/src/main/java/org/traccar/helper/BufferUtil.java index bbf12d738..9485c17c6 100644 --- a/src/main/java/org/traccar/helper/BufferUtil.java +++ b/src/main/java/org/traccar/helper/BufferUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -50,7 +50,7 @@ public final class BufferUtil { wrappedHaystack.writerIndex(endIndex - haystack.readerIndex()); } int result = ByteBufUtil.indexOf(needle, wrappedHaystack); - return result < 0 ? result : haystack.readerIndex() + startIndex + result; + return result < 0 ? result : startIndex + result; } } diff --git a/src/test/java/org/traccar/helper/BufferUtilTest.java b/src/test/java/org/traccar/helper/BufferUtilTest.java new file mode 100644 index 000000000..b539b5b28 --- /dev/null +++ b/src/test/java/org/traccar/helper/BufferUtilTest.java @@ -0,0 +1,35 @@ +package org.traccar.helper; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertEquals; + +public class BufferUtilTest { + + @Test + public void test1() { + ByteBuf buf = Unpooled.copiedBuffer("abcdef", StandardCharsets.US_ASCII); + assertEquals(2, BufferUtil.indexOf("cd", buf)); + } + + @Test + public void test2() { + ByteBuf buf = Unpooled.copiedBuffer("abcdef", StandardCharsets.US_ASCII); + buf.readerIndex(1); + buf.writerIndex(5); + assertEquals(2, BufferUtil.indexOf("cd", buf)); + } + + @Test + public void test3() { + ByteBuf buf = Unpooled.copiedBuffer("abcdefgh", StandardCharsets.US_ASCII); + buf.readerIndex(1); + buf.writerIndex(7); + assertEquals(3, BufferUtil.indexOf("de", buf, 2, 6)); + } + +} -- cgit v1.2.3 From 9de6ffeb75a15422e48ad7d9995b6670b336b3ff Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Feb 2022 11:04:36 -0800 Subject: Decode S168 network info --- .../org/traccar/protocol/S168ProtocolDecoder.java | 26 ++++++++++++++++++++++ .../traccar/protocol/S168ProtocolDecoderTest.java | 3 +++ 2 files changed, 29 insertions(+) diff --git a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java index 685364483..921141698 100644 --- a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java @@ -20,7 +20,10 @@ 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; @@ -48,6 +51,8 @@ public class S168ProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + Network network = new Network(); + String content = values[4]; String[] fragments = content.split(";"); for (String fragment : fragments) { @@ -73,11 +78,32 @@ public class S168ProtocolDecoder extends BaseProtocolDecoder { position.setCourse(Integer.parseInt(values[index++])); position.setAltitude(Integer.parseInt(values[index++])); break; + case "CELL": + int cellCount = Integer.parseInt(values[index++]); + int mcc = Integer.parseInt(values[index++], 16); + int mnc = Integer.parseInt(values[index++], 16); + for (int i = 0; i < cellCount; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, Integer.parseInt(values[index++], 16), Integer.parseInt(values[index++], 16), + Integer.parseInt(values[index++], 16))); + } + break; + case "WIFI": + int wifiCount = Integer.parseInt(values[index++]); + for (int i = 0; i < wifiCount; i++) { + network.addWifiAccessPoint(WifiAccessPoint.from( + values[index++].replace('-', ':'), Integer.parseInt(values[index++]))); + } + break; default: break; } } + if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { + position.setNetwork(network); + } + return position.getAttributes().containsKey(Position.KEY_SATELLITES) ? position : null; } diff --git a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java index 6bdf19182..c980e7abc 100644 --- a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class S168ProtocolDecoderTest extends ProtocolTest { var decoder = new S168ProtocolDecoder(null); + verifyPosition(decoder, text( + "S168#861118010104168#0715#0124#LOCA:W;CELL:6,1cc,0,5847,2c54cc1,1d,5847,cc98145,1b,5847,6259d03,e,5847,cc98141,1d,5847,6259e03,27,5847,32113ce,28;GDATA:V,0,220205152238,0.0,0.0,0,0,0;ALERT:0000;STATUS:99,52;WIFI:5,8C-AB-8E-9D-73-18,-56,60-3A-7C-E2-D3-85,-72,62-3A-7C-A2-D3-85,-72,00-00-00-00-00-00,-75,50-70-97-B1-80-1F,-82")); + verifyPosition(decoder, text( "S168#358511039001705#003a#01ca#LOCA:G;CELL:6,1cc,0,2479,de11150,2e,2479,d6e4546,31,2479,d6e4547,39,778c,787cc30,39,778c,787cc31,40,253f,6195502,32;GDATA:A,5,220117220950,22.779583,113.820633,5,296,35;ALERT:0080;STATUS:98,73;;FARM:0,0009,0000,010a,20220117220950;WIFI:10,CC-08-FB-A5-49-B3,-28,08-40-F3-7F-6C-A9,-59,A4-29-40-65-2C-42,-74,80-89-17-A5-6F-7B,-82,80-EA-07-82-93-C6,-82,FC-37-2B-34-D6-A1,-83,34-6B-5B-A9-49-15,-83,BC-46-99-B3-51-10,-84,BC-54-FC-53-0A-D1,-84,3C-CD-57-67-D1-32,-85")); -- cgit v1.2.3 From f258382b1203fa31d150e0b090fe5afdb01ede6b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Feb 2022 16:32:35 -0800 Subject: Decode S168 status info --- src/main/java/org/traccar/protocol/S168ProtocolDecoder.java | 13 ++++++++++++- .../java/org/traccar/protocol/S168ProtocolDecoderTest.java | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java index 921141698..6d565517b 100644 --- a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java @@ -95,6 +95,10 @@ public class S168ProtocolDecoder extends BaseProtocolDecoder { values[index++].replace('-', ':'), Integer.parseInt(values[index++]))); } break; + case "STATUS": + position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[index++])); + position.set(Position.KEY_RSSI, Integer.parseInt(values[index++])); + break; default: break; } @@ -103,8 +107,15 @@ public class S168ProtocolDecoder extends BaseProtocolDecoder { if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { position.setNetwork(network); } + if (!position.getAttributes().containsKey(Position.KEY_SATELLITES)) { + getLastLocation(position, null); + } - return position.getAttributes().containsKey(Position.KEY_SATELLITES) ? position : null; + if (position.getNetwork() != null || !position.getAttributes().isEmpty()) { + return position; + } else { + return null; + } } } diff --git a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java index c980e7abc..ec795c9eb 100644 --- a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class S168ProtocolDecoderTest extends ProtocolTest { var decoder = new S168ProtocolDecoder(null); + verifyAttributes(decoder, text( + "S168#861118010104168#00ec#0016#SYNC:0093;STATUS:91,51")); + verifyPosition(decoder, text( "S168#861118010104168#0715#0124#LOCA:W;CELL:6,1cc,0,5847,2c54cc1,1d,5847,cc98145,1b,5847,6259d03,e,5847,cc98141,1d,5847,6259e03,27,5847,32113ce,28;GDATA:V,0,220205152238,0.0,0.0,0,0,0;ALERT:0000;STATUS:99,52;WIFI:5,8C-AB-8E-9D-73-18,-56,60-3A-7C-E2-D3-85,-72,62-3A-7C-A2-D3-85,-72,00-00-00-00-00-00,-75,50-70-97-B1-80-1F,-82")); -- cgit v1.2.3 From 6ac6520eb0c96dcd690a5bd777a275673c7cd6e3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Feb 2022 08:54:22 -0800 Subject: Create storage package --- .../java/org/traccar/database/DataManager.java | 3 + .../java/org/traccar/database/QueryBuilder.java | 485 --------------------- .../java/org/traccar/database/QueryExtended.java | 27 -- .../java/org/traccar/database/QueryIgnore.java | 26 -- src/main/java/org/traccar/model/Calendar.java | 2 +- src/main/java/org/traccar/model/Command.java | 2 +- src/main/java/org/traccar/model/Device.java | 4 +- src/main/java/org/traccar/model/Geofence.java | 2 +- src/main/java/org/traccar/model/Notification.java | 2 +- src/main/java/org/traccar/model/Position.java | 2 +- src/main/java/org/traccar/model/Server.java | 2 +- src/main/java/org/traccar/model/User.java | 4 +- .../java/org/traccar/storage/QueryBuilder.java | 485 +++++++++++++++++++++ .../java/org/traccar/storage/QueryExtended.java | 27 ++ src/main/java/org/traccar/storage/QueryIgnore.java | 26 ++ 15 files changed, 551 insertions(+), 548 deletions(-) delete mode 100644 src/main/java/org/traccar/database/QueryBuilder.java delete mode 100644 src/main/java/org/traccar/database/QueryExtended.java delete mode 100644 src/main/java/org/traccar/database/QueryIgnore.java create mode 100644 src/main/java/org/traccar/storage/QueryBuilder.java create mode 100644 src/main/java/org/traccar/storage/QueryExtended.java create mode 100644 src/main/java/org/traccar/storage/QueryIgnore.java diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index ebd0dcade..199167419 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -47,6 +47,9 @@ import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.Statistics; import org.traccar.model.User; +import org.traccar.storage.QueryBuilder; +import org.traccar.storage.QueryExtended; +import org.traccar.storage.QueryIgnore; import javax.sql.DataSource; import java.beans.Introspector; diff --git a/src/main/java/org/traccar/database/QueryBuilder.java b/src/main/java/org/traccar/database/QueryBuilder.java deleted file mode 100644 index 396cbf562..000000000 --- a/src/main/java/org/traccar/database/QueryBuilder.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright 2015 - 2020 Anton Tananaev (anton@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.database; - -import com.fasterxml.jackson.core.JsonProcessingException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Permission; - -import javax.sql.DataSource; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public final class QueryBuilder { - - private static final Logger LOGGER = LoggerFactory.getLogger(QueryBuilder.class); - - private final Map> indexMap = new HashMap<>(); - private Connection connection; - private PreparedStatement statement; - private final String query; - private final boolean returnGeneratedKeys; - - private QueryBuilder(DataSource dataSource, String query, boolean returnGeneratedKeys) throws SQLException { - this.query = query; - this.returnGeneratedKeys = returnGeneratedKeys; - if (query != null) { - connection = dataSource.getConnection(); - String parsedQuery = parse(query.trim(), indexMap); - try { - if (returnGeneratedKeys) { - statement = connection.prepareStatement(parsedQuery, Statement.RETURN_GENERATED_KEYS); - } else { - statement = connection.prepareStatement(parsedQuery); - } - } catch (SQLException error) { - connection.close(); - throw error; - } - } - } - - private static String parse(String query, Map> paramMap) { - - int length = query.length(); - StringBuilder parsedQuery = new StringBuilder(length); - boolean inSingleQuote = false; - boolean inDoubleQuote = false; - int index = 1; - - for (int i = 0; i < length; i++) { - - char c = query.charAt(i); - - // String end - if (inSingleQuote) { - if (c == '\'') { - inSingleQuote = false; - } - } else if (inDoubleQuote) { - if (c == '"') { - inDoubleQuote = false; - } - } else { - - // String begin - if (c == '\'') { - inSingleQuote = true; - } else if (c == '"') { - inDoubleQuote = true; - } else if (c == ':' && i + 1 < length - && Character.isJavaIdentifierStart(query.charAt(i + 1))) { - - // Identifier name - int j = i + 2; - while (j < length && Character.isJavaIdentifierPart(query.charAt(j))) { - j++; - } - - String name = query.substring(i + 1, j); - c = '?'; - i += name.length(); - name = name.toLowerCase(); - - // Add to list - List indexList = paramMap.computeIfAbsent(name, k -> new LinkedList<>()); - indexList.add(index); - - index++; - } - } - - parsedQuery.append(c); - } - - return parsedQuery.toString(); - } - - public static QueryBuilder create(DataSource dataSource, String query) throws SQLException { - return new QueryBuilder(dataSource, query, false); - } - - public static QueryBuilder create( - DataSource dataSource, String query, boolean returnGeneratedKeys) throws SQLException { - return new QueryBuilder(dataSource, query, returnGeneratedKeys); - } - - private List indexes(String name) { - name = name.toLowerCase(); - List result = indexMap.get(name); - if (result == null) { - result = new LinkedList<>(); - } - return result; - } - - public QueryBuilder setBoolean(String name, boolean value) throws SQLException { - for (int i : indexes(name)) { - try { - statement.setBoolean(i, value); - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setInteger(String name, int value) throws SQLException { - for (int i : indexes(name)) { - try { - statement.setInt(i, value); - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setLong(String name, long value) throws SQLException { - return setLong(name, value, false); - } - - public QueryBuilder setLong(String name, long value, boolean nullIfZero) throws SQLException { - for (int i : indexes(name)) { - try { - if (value == 0 && nullIfZero) { - statement.setNull(i, Types.INTEGER); - } else { - statement.setLong(i, value); - } - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setDouble(String name, double value) throws SQLException { - for (int i : indexes(name)) { - try { - statement.setDouble(i, value); - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setString(String name, String value) throws SQLException { - for (int i : indexes(name)) { - try { - if (value == null) { - statement.setNull(i, Types.VARCHAR); - } else { - statement.setString(i, value); - } - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setDate(String name, Date value) throws SQLException { - for (int i : indexes(name)) { - try { - if (value == null) { - statement.setNull(i, Types.TIMESTAMP); - } else { - statement.setTimestamp(i, new Timestamp(value.getTime())); - } - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setBlob(String name, byte[] value) throws SQLException { - for (int i : indexes(name)) { - try { - if (value == null) { - statement.setNull(i, Types.BLOB); - } else { - statement.setBytes(i, value); - } - } catch (SQLException error) { - statement.close(); - connection.close(); - throw error; - } - } - return this; - } - - public QueryBuilder setObject(Object object) throws SQLException { - - Method[] methods = object.getClass().getMethods(); - - for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 - && !method.isAnnotationPresent(QueryIgnore.class)) { - String name = method.getName().substring(3); - try { - if (method.getReturnType().equals(boolean.class)) { - setBoolean(name, (Boolean) method.invoke(object)); - } else if (method.getReturnType().equals(int.class)) { - setInteger(name, (Integer) method.invoke(object)); - } else if (method.getReturnType().equals(long.class)) { - setLong(name, (Long) method.invoke(object), name.endsWith("Id")); - } else if (method.getReturnType().equals(double.class)) { - setDouble(name, (Double) method.invoke(object)); - } else if (method.getReturnType().equals(String.class)) { - setString(name, (String) method.invoke(object)); - } else if (method.getReturnType().equals(Date.class)) { - setDate(name, (Date) method.invoke(object)); - } else if (method.getReturnType().equals(byte[].class)) { - setBlob(name, (byte[]) method.invoke(object)); - } else { - setString(name, Context.getObjectMapper().writeValueAsString(method.invoke(object))); - } - } catch (IllegalAccessException | InvocationTargetException | JsonProcessingException error) { - LOGGER.warn("Get property error", error); - } - } - } - - return this; - } - - private interface ResultSetProcessor { - void process(T object, ResultSet resultSet) throws SQLException; - } - - public T executeQuerySingle(Class clazz) throws SQLException { - Collection result = executeQuery(clazz); - if (!result.isEmpty()) { - return result.iterator().next(); - } else { - return null; - } - } - - private void addProcessors( - List> processors, - final Class parameterType, final Method method, final String name) { - - if (parameterType.equals(boolean.class)) { - processors.add((object, resultSet) -> { - try { - method.invoke(object, resultSet.getBoolean(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - }); - } else if (parameterType.equals(int.class)) { - processors.add((object, resultSet) -> { - try { - method.invoke(object, resultSet.getInt(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - }); - } else if (parameterType.equals(long.class)) { - processors.add((object, resultSet) -> { - try { - method.invoke(object, resultSet.getLong(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - }); - } else if (parameterType.equals(double.class)) { - processors.add((object, resultSet) -> { - try { - method.invoke(object, resultSet.getDouble(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - }); - } else if (parameterType.equals(String.class)) { - processors.add((object, resultSet) -> { - try { - method.invoke(object, resultSet.getString(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - }); - } else if (parameterType.equals(Date.class)) { - processors.add((object, resultSet) -> { - try { - Timestamp timestamp = resultSet.getTimestamp(name); - if (timestamp != null) { - method.invoke(object, new Date(timestamp.getTime())); - } - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - }); - } else if (parameterType.equals(byte[].class)) { - processors.add((object, resultSet) -> { - try { - method.invoke(object, resultSet.getBytes(name)); - } catch (IllegalAccessException | InvocationTargetException error) { - LOGGER.warn("Set property error", error); - } - }); - } else { - processors.add((object, resultSet) -> { - String value = resultSet.getString(name); - if (value != null && !value.isEmpty()) { - try { - method.invoke(object, Context.getObjectMapper().readValue(value, parameterType)); - } catch (InvocationTargetException | IllegalAccessException | IOException error) { - LOGGER.warn("Set property error", error); - } - } - }); - } - } - - public Collection executeQuery(Class clazz) throws SQLException { - List result = new LinkedList<>(); - - if (query != null) { - - try { - - try (ResultSet resultSet = statement.executeQuery()) { - - ResultSetMetaData resultMetaData = resultSet.getMetaData(); - - List> processors = new LinkedList<>(); - - Method[] methods = clazz.getMethods(); - - for (final Method method : methods) { - if (method.getName().startsWith("set") && method.getParameterTypes().length == 1 - && !method.isAnnotationPresent(QueryIgnore.class)) { - - final String name = method.getName().substring(3); - - // Check if column exists - boolean column = false; - for (int i = 1; i <= resultMetaData.getColumnCount(); i++) { - if (name.equalsIgnoreCase(resultMetaData.getColumnLabel(i))) { - column = true; - break; - } - } - if (!column) { - continue; - } - - addProcessors(processors, method.getParameterTypes()[0], method, name); - } - } - - while (resultSet.next()) { - try { - T object = clazz.getDeclaredConstructor().newInstance(); - for (ResultSetProcessor processor : processors) { - processor.process(object, resultSet); - } - result.add(object); - } catch (ReflectiveOperationException e) { - throw new IllegalArgumentException(); - } - } - } - - } finally { - statement.close(); - connection.close(); - } - } - - return result; - } - - public long executeUpdate() throws SQLException { - - if (query != null) { - try { - statement.execute(); - if (returnGeneratedKeys) { - ResultSet resultSet = statement.getGeneratedKeys(); - if (resultSet.next()) { - return resultSet.getLong(1); - } - } - } finally { - statement.close(); - connection.close(); - } - } - return 0; - } - - public Collection executePermissionsQuery() throws SQLException, ClassNotFoundException { - List result = new LinkedList<>(); - if (query != null) { - try { - try (ResultSet resultSet = statement.executeQuery()) { - ResultSetMetaData resultMetaData = resultSet.getMetaData(); - while (resultSet.next()) { - LinkedHashMap map = new LinkedHashMap<>(); - for (int i = 1; i <= resultMetaData.getColumnCount(); i++) { - String label = resultMetaData.getColumnLabel(i); - map.put(label, resultSet.getLong(label)); - } - result.add(new Permission(map)); - } - } - } finally { - statement.close(); - connection.close(); - } - } - - return result; - } - -} diff --git a/src/main/java/org/traccar/database/QueryExtended.java b/src/main/java/org/traccar/database/QueryExtended.java deleted file mode 100644 index 07bc2c211..000000000 --- a/src/main/java/org/traccar/database/QueryExtended.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.database; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface QueryExtended { -} diff --git a/src/main/java/org/traccar/database/QueryIgnore.java b/src/main/java/org/traccar/database/QueryIgnore.java deleted file mode 100644 index ac835cf2f..000000000 --- a/src/main/java/org/traccar/database/QueryIgnore.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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.database; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface QueryIgnore { -} diff --git a/src/main/java/org/traccar/model/Calendar.java b/src/main/java/org/traccar/model/Calendar.java index 0b45ca6c8..af6364626 100644 --- a/src/main/java/org/traccar/model/Calendar.java +++ b/src/main/java/org/traccar/model/Calendar.java @@ -24,7 +24,7 @@ import net.fortuna.ical4j.filter.predicate.PeriodRule; import net.fortuna.ical4j.model.DateTime; import net.fortuna.ical4j.model.Period; import net.fortuna.ical4j.model.component.CalendarComponent; -import org.traccar.database.QueryIgnore; +import org.traccar.storage.QueryIgnore; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/src/main/java/org/traccar/model/Command.java b/src/main/java/org/traccar/model/Command.java index 99930d1e6..71bc232e9 100644 --- a/src/main/java/org/traccar/model/Command.java +++ b/src/main/java/org/traccar/model/Command.java @@ -15,7 +15,7 @@ */ package org.traccar.model; -import org.traccar.database.QueryIgnore; +import org.traccar.storage.QueryIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 0c9be932d..46de8003d 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -18,8 +18,8 @@ package org.traccar.model; import java.util.Date; import java.util.List; -import org.traccar.database.QueryExtended; -import org.traccar.database.QueryIgnore; +import org.traccar.storage.QueryExtended; +import org.traccar.storage.QueryIgnore; public class Device extends GroupedModel { diff --git a/src/main/java/org/traccar/model/Geofence.java b/src/main/java/org/traccar/model/Geofence.java index 85f392f99..a451da9f5 100644 --- a/src/main/java/org/traccar/model/Geofence.java +++ b/src/main/java/org/traccar/model/Geofence.java @@ -19,7 +19,7 @@ import java.text.ParseException; import org.traccar.Context; import org.traccar.config.Keys; -import org.traccar.database.QueryIgnore; +import org.traccar.storage.QueryIgnore; import org.traccar.geofence.GeofenceCircle; import org.traccar.geofence.GeofenceGeometry; import org.traccar.geofence.GeofencePolygon; diff --git a/src/main/java/org/traccar/model/Notification.java b/src/main/java/org/traccar/model/Notification.java index f1983a03a..01ca2711c 100644 --- a/src/main/java/org/traccar/model/Notification.java +++ b/src/main/java/org/traccar/model/Notification.java @@ -18,7 +18,7 @@ package org.traccar.model; import java.util.HashSet; import java.util.Set; -import org.traccar.database.QueryIgnore; +import org.traccar.storage.QueryIgnore; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 09d25e832..bbea58901 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -17,7 +17,7 @@ package org.traccar.model; import java.util.Date; -import org.traccar.database.QueryIgnore; +import org.traccar.storage.QueryIgnore; public class Position extends Message { diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index 03d087cac..fdb071a18 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -17,7 +17,7 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.traccar.Context; -import org.traccar.database.QueryIgnore; +import org.traccar.storage.QueryIgnore; @JsonIgnoreProperties(ignoreUnknown = true) public class Server extends ExtendedModel { diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 359bdc2c2..447cf691c 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -17,8 +17,8 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnore; -import org.traccar.database.QueryExtended; -import org.traccar.database.QueryIgnore; +import org.traccar.storage.QueryExtended; +import org.traccar.storage.QueryIgnore; import org.traccar.helper.Hashing; import java.util.Date; diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java new file mode 100644 index 000000000..c7800f19b --- /dev/null +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -0,0 +1,485 @@ +/* + * Copyright 2015 - 2020 Anton Tananaev (anton@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.storage; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.Context; +import org.traccar.model.Permission; + +import javax.sql.DataSource; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; +import java.sql.Types; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public final class QueryBuilder { + + private static final Logger LOGGER = LoggerFactory.getLogger(QueryBuilder.class); + + private final Map> indexMap = new HashMap<>(); + private Connection connection; + private PreparedStatement statement; + private final String query; + private final boolean returnGeneratedKeys; + + private QueryBuilder(DataSource dataSource, String query, boolean returnGeneratedKeys) throws SQLException { + this.query = query; + this.returnGeneratedKeys = returnGeneratedKeys; + if (query != null) { + connection = dataSource.getConnection(); + String parsedQuery = parse(query.trim(), indexMap); + try { + if (returnGeneratedKeys) { + statement = connection.prepareStatement(parsedQuery, Statement.RETURN_GENERATED_KEYS); + } else { + statement = connection.prepareStatement(parsedQuery); + } + } catch (SQLException error) { + connection.close(); + throw error; + } + } + } + + private static String parse(String query, Map> paramMap) { + + int length = query.length(); + StringBuilder parsedQuery = new StringBuilder(length); + boolean inSingleQuote = false; + boolean inDoubleQuote = false; + int index = 1; + + for (int i = 0; i < length; i++) { + + char c = query.charAt(i); + + // String end + if (inSingleQuote) { + if (c == '\'') { + inSingleQuote = false; + } + } else if (inDoubleQuote) { + if (c == '"') { + inDoubleQuote = false; + } + } else { + + // String begin + if (c == '\'') { + inSingleQuote = true; + } else if (c == '"') { + inDoubleQuote = true; + } else if (c == ':' && i + 1 < length + && Character.isJavaIdentifierStart(query.charAt(i + 1))) { + + // Identifier name + int j = i + 2; + while (j < length && Character.isJavaIdentifierPart(query.charAt(j))) { + j++; + } + + String name = query.substring(i + 1, j); + c = '?'; + i += name.length(); + name = name.toLowerCase(); + + // Add to list + List indexList = paramMap.computeIfAbsent(name, k -> new LinkedList<>()); + indexList.add(index); + + index++; + } + } + + parsedQuery.append(c); + } + + return parsedQuery.toString(); + } + + public static QueryBuilder create(DataSource dataSource, String query) throws SQLException { + return new QueryBuilder(dataSource, query, false); + } + + public static QueryBuilder create( + DataSource dataSource, String query, boolean returnGeneratedKeys) throws SQLException { + return new QueryBuilder(dataSource, query, returnGeneratedKeys); + } + + private List indexes(String name) { + name = name.toLowerCase(); + List result = indexMap.get(name); + if (result == null) { + result = new LinkedList<>(); + } + return result; + } + + public QueryBuilder setBoolean(String name, boolean value) throws SQLException { + for (int i : indexes(name)) { + try { + statement.setBoolean(i, value); + } catch (SQLException error) { + statement.close(); + connection.close(); + throw error; + } + } + return this; + } + + public QueryBuilder setInteger(String name, int value) throws SQLException { + for (int i : indexes(name)) { + try { + statement.setInt(i, value); + } catch (SQLException error) { + statement.close(); + connection.close(); + throw error; + } + } + return this; + } + + public QueryBuilder setLong(String name, long value) throws SQLException { + return setLong(name, value, false); + } + + public QueryBuilder setLong(String name, long value, boolean nullIfZero) throws SQLException { + for (int i : indexes(name)) { + try { + if (value == 0 && nullIfZero) { + statement.setNull(i, Types.INTEGER); + } else { + statement.setLong(i, value); + } + } catch (SQLException error) { + statement.close(); + connection.close(); + throw error; + } + } + return this; + } + + public QueryBuilder setDouble(String name, double value) throws SQLException { + for (int i : indexes(name)) { + try { + statement.setDouble(i, value); + } catch (SQLException error) { + statement.close(); + connection.close(); + throw error; + } + } + return this; + } + + public QueryBuilder setString(String name, String value) throws SQLException { + for (int i : indexes(name)) { + try { + if (value == null) { + statement.setNull(i, Types.VARCHAR); + } else { + statement.setString(i, value); + } + } catch (SQLException error) { + statement.close(); + connection.close(); + throw error; + } + } + return this; + } + + public QueryBuilder setDate(String name, Date value) throws SQLException { + for (int i : indexes(name)) { + try { + if (value == null) { + statement.setNull(i, Types.TIMESTAMP); + } else { + statement.setTimestamp(i, new Timestamp(value.getTime())); + } + } catch (SQLException error) { + statement.close(); + connection.close(); + throw error; + } + } + return this; + } + + public QueryBuilder setBlob(String name, byte[] value) throws SQLException { + for (int i : indexes(name)) { + try { + if (value == null) { + statement.setNull(i, Types.BLOB); + } else { + statement.setBytes(i, value); + } + } catch (SQLException error) { + statement.close(); + connection.close(); + throw error; + } + } + return this; + } + + public QueryBuilder setObject(Object object) throws SQLException { + + Method[] methods = object.getClass().getMethods(); + + for (Method method : methods) { + if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 + && !method.isAnnotationPresent(QueryIgnore.class)) { + String name = method.getName().substring(3); + try { + if (method.getReturnType().equals(boolean.class)) { + setBoolean(name, (Boolean) method.invoke(object)); + } else if (method.getReturnType().equals(int.class)) { + setInteger(name, (Integer) method.invoke(object)); + } else if (method.getReturnType().equals(long.class)) { + setLong(name, (Long) method.invoke(object), name.endsWith("Id")); + } else if (method.getReturnType().equals(double.class)) { + setDouble(name, (Double) method.invoke(object)); + } else if (method.getReturnType().equals(String.class)) { + setString(name, (String) method.invoke(object)); + } else if (method.getReturnType().equals(Date.class)) { + setDate(name, (Date) method.invoke(object)); + } else if (method.getReturnType().equals(byte[].class)) { + setBlob(name, (byte[]) method.invoke(object)); + } else { + setString(name, Context.getObjectMapper().writeValueAsString(method.invoke(object))); + } + } catch (IllegalAccessException | InvocationTargetException | JsonProcessingException error) { + LOGGER.warn("Get property error", error); + } + } + } + + return this; + } + + private interface ResultSetProcessor { + void process(T object, ResultSet resultSet) throws SQLException; + } + + public T executeQuerySingle(Class clazz) throws SQLException { + Collection result = executeQuery(clazz); + if (!result.isEmpty()) { + return result.iterator().next(); + } else { + return null; + } + } + + private void addProcessors( + List> processors, + final Class parameterType, final Method method, final String name) { + + if (parameterType.equals(boolean.class)) { + processors.add((object, resultSet) -> { + try { + method.invoke(object, resultSet.getBoolean(name)); + } catch (IllegalAccessException | InvocationTargetException error) { + LOGGER.warn("Set property error", error); + } + }); + } else if (parameterType.equals(int.class)) { + processors.add((object, resultSet) -> { + try { + method.invoke(object, resultSet.getInt(name)); + } catch (IllegalAccessException | InvocationTargetException error) { + LOGGER.warn("Set property error", error); + } + }); + } else if (parameterType.equals(long.class)) { + processors.add((object, resultSet) -> { + try { + method.invoke(object, resultSet.getLong(name)); + } catch (IllegalAccessException | InvocationTargetException error) { + LOGGER.warn("Set property error", error); + } + }); + } else if (parameterType.equals(double.class)) { + processors.add((object, resultSet) -> { + try { + method.invoke(object, resultSet.getDouble(name)); + } catch (IllegalAccessException | InvocationTargetException error) { + LOGGER.warn("Set property error", error); + } + }); + } else if (parameterType.equals(String.class)) { + processors.add((object, resultSet) -> { + try { + method.invoke(object, resultSet.getString(name)); + } catch (IllegalAccessException | InvocationTargetException error) { + LOGGER.warn("Set property error", error); + } + }); + } else if (parameterType.equals(Date.class)) { + processors.add((object, resultSet) -> { + try { + Timestamp timestamp = resultSet.getTimestamp(name); + if (timestamp != null) { + method.invoke(object, new Date(timestamp.getTime())); + } + } catch (IllegalAccessException | InvocationTargetException error) { + LOGGER.warn("Set property error", error); + } + }); + } else if (parameterType.equals(byte[].class)) { + processors.add((object, resultSet) -> { + try { + method.invoke(object, resultSet.getBytes(name)); + } catch (IllegalAccessException | InvocationTargetException error) { + LOGGER.warn("Set property error", error); + } + }); + } else { + processors.add((object, resultSet) -> { + String value = resultSet.getString(name); + if (value != null && !value.isEmpty()) { + try { + method.invoke(object, Context.getObjectMapper().readValue(value, parameterType)); + } catch (InvocationTargetException | IllegalAccessException | IOException error) { + LOGGER.warn("Set property error", error); + } + } + }); + } + } + + public Collection executeQuery(Class clazz) throws SQLException { + List result = new LinkedList<>(); + + if (query != null) { + + try { + + try (ResultSet resultSet = statement.executeQuery()) { + + ResultSetMetaData resultMetaData = resultSet.getMetaData(); + + List> processors = new LinkedList<>(); + + Method[] methods = clazz.getMethods(); + + for (final Method method : methods) { + if (method.getName().startsWith("set") && method.getParameterTypes().length == 1 + && !method.isAnnotationPresent(QueryIgnore.class)) { + + final String name = method.getName().substring(3); + + // Check if column exists + boolean column = false; + for (int i = 1; i <= resultMetaData.getColumnCount(); i++) { + if (name.equalsIgnoreCase(resultMetaData.getColumnLabel(i))) { + column = true; + break; + } + } + if (!column) { + continue; + } + + addProcessors(processors, method.getParameterTypes()[0], method, name); + } + } + + while (resultSet.next()) { + try { + T object = clazz.getDeclaredConstructor().newInstance(); + for (ResultSetProcessor processor : processors) { + processor.process(object, resultSet); + } + result.add(object); + } catch (ReflectiveOperationException e) { + throw new IllegalArgumentException(); + } + } + } + + } finally { + statement.close(); + connection.close(); + } + } + + return result; + } + + public long executeUpdate() throws SQLException { + + if (query != null) { + try { + statement.execute(); + if (returnGeneratedKeys) { + ResultSet resultSet = statement.getGeneratedKeys(); + if (resultSet.next()) { + return resultSet.getLong(1); + } + } + } finally { + statement.close(); + connection.close(); + } + } + return 0; + } + + public Collection executePermissionsQuery() throws SQLException, ClassNotFoundException { + List result = new LinkedList<>(); + if (query != null) { + try { + try (ResultSet resultSet = statement.executeQuery()) { + ResultSetMetaData resultMetaData = resultSet.getMetaData(); + while (resultSet.next()) { + LinkedHashMap map = new LinkedHashMap<>(); + for (int i = 1; i <= resultMetaData.getColumnCount(); i++) { + String label = resultMetaData.getColumnLabel(i); + map.put(label, resultSet.getLong(label)); + } + result.add(new Permission(map)); + } + } + } finally { + statement.close(); + connection.close(); + } + } + + return result; + } + +} diff --git a/src/main/java/org/traccar/storage/QueryExtended.java b/src/main/java/org/traccar/storage/QueryExtended.java new file mode 100644 index 000000000..3796f1f40 --- /dev/null +++ b/src/main/java/org/traccar/storage/QueryExtended.java @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@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.storage; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface QueryExtended { +} diff --git a/src/main/java/org/traccar/storage/QueryIgnore.java b/src/main/java/org/traccar/storage/QueryIgnore.java new file mode 100644 index 000000000..553d4b9fc --- /dev/null +++ b/src/main/java/org/traccar/storage/QueryIgnore.java @@ -0,0 +1,26 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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.storage; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface QueryIgnore { +} -- cgit v1.2.3 From 79730c0bf5d5fbe83204e52e73b4bf47964c5a2d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Feb 2022 17:01:56 -0800 Subject: Implement new storage framework --- .../java/org/traccar/storage/DatabaseStorage.java | 164 +++++++++++++++++++++ .../java/org/traccar/storage/MemoryStorage.java | 27 ++++ .../java/org/traccar/storage/QueryBuilder.java | 26 +++- src/main/java/org/traccar/storage/Storage.java | 25 ++++ .../java/org/traccar/storage/StorageException.java | 17 +++ src/main/java/org/traccar/storage/StorageName.java | 12 ++ .../java/org/traccar/storage/query/Columns.java | 63 ++++++++ .../java/org/traccar/storage/query/Condition.java | 83 +++++++++++ src/main/java/org/traccar/storage/query/Order.java | 25 ++++ .../java/org/traccar/storage/query/Request.java | 27 ++++ 10 files changed, 464 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/traccar/storage/DatabaseStorage.java create mode 100644 src/main/java/org/traccar/storage/MemoryStorage.java create mode 100644 src/main/java/org/traccar/storage/Storage.java create mode 100644 src/main/java/org/traccar/storage/StorageException.java create mode 100644 src/main/java/org/traccar/storage/StorageName.java create mode 100644 src/main/java/org/traccar/storage/query/Columns.java create mode 100644 src/main/java/org/traccar/storage/query/Condition.java create mode 100644 src/main/java/org/traccar/storage/query/Order.java create mode 100644 src/main/java/org/traccar/storage/query/Request.java diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java new file mode 100644 index 000000000..0bcab7d20 --- /dev/null +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -0,0 +1,164 @@ +package org.traccar.storage; + +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; + +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class DatabaseStorage extends Storage { + + private final DataSource dataSource; + + public DatabaseStorage(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Override + public List getObjects(Class clazz, Request request) throws StorageException { + StringBuilder query = new StringBuilder("SELECT "); + query.append(formatColumns(request.getColumns(), clazz, c -> c)); + query.append(" FROM ").append(getTableName(clazz)); + query.append(formatCondition(request.getCondition())); + query.append(formatOrder(request.getOrder())); + try { + QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { + builder.setValue(variable.getKey(), variable.getValue()); + } + return builder.executeQuery(clazz); + } catch (SQLException e) { + throw new StorageException(e); + } + } + + @Override + public long addObject(T entity, Request request) throws StorageException { + StringBuilder query = new StringBuilder("INSERT INTO "); + query.append(getTableName(entity.getClass())); + query.append("("); + query.append(formatColumns(request.getColumns(), entity.getClass(), c -> c)); + query.append(") VALUES ("); + query.append(formatColumns(request.getColumns(), entity.getClass(), c -> ':' + c)); + query.append(")"); + try { + QueryBuilder builder = QueryBuilder.create(dataSource, query.toString(), true); + builder.setObject(entity); + return builder.executeUpdate(); + } catch (SQLException e) { + throw new StorageException(e); + } + } + + @Override + public void updateObject(T entity, Request request) throws StorageException { + StringBuilder query = new StringBuilder("UPDATE "); + query.append(getTableName(entity.getClass())); + query.append(" SET "); + query.append(formatColumns(request.getColumns(), entity.getClass(), c -> c + " = :" + c)); + query.append(formatCondition(request.getCondition())); + try { + QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + builder.setObject(entity); + for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { + builder.setValue(variable.getKey(), variable.getValue()); + } + builder.executeUpdate(); + } catch (SQLException e) { + throw new StorageException(e); + } + } + + @Override + public void removeObject(Class clazz, Request request) throws StorageException { + StringBuilder query = new StringBuilder("DELETE FROM "); + query.append(getTableName(clazz)); + query.append(formatCondition(request.getCondition())); + try { + QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { + builder.setValue(variable.getKey(), variable.getValue()); + } + builder.executeUpdate(); + } catch (SQLException e) { + throw new StorageException(e); + } + } + + private String getTableName(Class clazz) throws StorageException { + StorageName storageName = clazz.getAnnotation(StorageName.class); + if (storageName == null) { + throw new StorageException("StorageName annotation is missing"); + } + return storageName.value(); + } + + private Map getConditionVariables(Condition genericCondition) { + Map result = new HashMap<>(); + if (genericCondition instanceof Condition.Equals) { + Condition.Equals condition = (Condition.Equals) genericCondition; + result.put(condition.getVariable(), condition.getValue()); + } else if (genericCondition instanceof Condition.Between) { + Condition.Between condition = (Condition.Between) genericCondition; + result.put(condition.getFromVariable(), condition.getFromValue()); + result.put(condition.getToVariable(), condition.getToValue()); + } + return result; + } + + private String formatColumns(Columns columns, Class clazz, Function mapper) { + return columns.getColumns(clazz).stream().map(mapper).collect(Collectors.joining(", ")); + } + + private String formatCondition(Condition genericCondition) { + StringBuilder result = new StringBuilder(); + if (genericCondition != null) { + result.append(" WHERE "); + if (genericCondition instanceof Condition.Equals) { + + Condition.Equals condition = (Condition.Equals) genericCondition; + result.append(condition.getColumn()); + result.append(" == :"); + result.append(condition.getVariable()); + + } else if (genericCondition instanceof Condition.Between) { + + Condition.Between condition = (Condition.Between) genericCondition; + result.append(condition.getColumn()); + result.append(" BETWEEN :"); + result.append(condition.getFromVariable()); + result.append(" AND :"); + result.append(condition.getToVariable()); + + } else if (genericCondition instanceof Condition.And) { + + Condition.And condition = (Condition.And) genericCondition; + result.append(formatCondition(condition.getFirst())); + result.append(" AND "); + result.append(formatCondition(condition.getSecond())); + + } + } + return result.toString(); + } + + private String formatOrder(Order order) { + StringBuilder result = new StringBuilder(); + if (order != null) { + result.append(" ORDER BY "); + result.append(order.getColumn()); + if (order.getDescending()) { + result.append(" DESC"); + } + } + return result.toString(); + } + +} diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java new file mode 100644 index 000000000..0ebd3b87e --- /dev/null +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -0,0 +1,27 @@ +package org.traccar.storage; + +import org.traccar.storage.query.Request; + +import java.util.List; + +public class MemoryStorage extends Storage { + + @Override + public List getObjects(Class clazz, Request request) throws StorageException { + return null; + } + + @Override + public long addObject(T entity, Request request) throws StorageException { + return 0; + } + + @Override + public void updateObject(T entity, Request request) throws StorageException { + } + + @Override + public void removeObject(Class clazz, Request request) throws StorageException { + } + +} diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index c7800f19b..838472c8b 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,6 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; import java.sql.Types; -import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; @@ -255,6 +254,23 @@ public final class QueryBuilder { return this; } + public QueryBuilder setValue(String name, Object value) throws SQLException { + if (value instanceof Boolean) { + setBoolean(name, (Boolean) value); + } else if (value instanceof Integer) { + setInteger(name, (Integer) value); + } else if (value instanceof Long) { + setLong(name, (Long) value); + } else if (value instanceof Double) { + setDouble(name, (Double) value); + } else if (value instanceof String) { + setString(name, (String) value); + } else if (value instanceof Date) { + setDate(name, (Date) value); + } + return this; + } + public QueryBuilder setObject(Object object) throws SQLException { Method[] methods = object.getClass().getMethods(); @@ -295,7 +311,7 @@ public final class QueryBuilder { } public T executeQuerySingle(Class clazz) throws SQLException { - Collection result = executeQuery(clazz); + List result = executeQuery(clazz); if (!result.isEmpty()) { return result.iterator().next(); } else { @@ -380,7 +396,7 @@ public final class QueryBuilder { } } - public Collection executeQuery(Class clazz) throws SQLException { + public List executeQuery(Class clazz) throws SQLException { List result = new LinkedList<>(); if (query != null) { @@ -458,7 +474,7 @@ public final class QueryBuilder { return 0; } - public Collection executePermissionsQuery() throws SQLException, ClassNotFoundException { + public List executePermissionsQuery() throws SQLException, ClassNotFoundException { List result = new LinkedList<>(); if (query != null) { try { diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java new file mode 100644 index 000000000..b95ce9505 --- /dev/null +++ b/src/main/java/org/traccar/storage/Storage.java @@ -0,0 +1,25 @@ +package org.traccar.storage; + +import org.traccar.storage.query.Request; + +import java.util.List; + +public abstract class Storage { + + abstract List getObjects(Class clazz, Request request) throws StorageException; + + abstract long addObject(T entity, Request request) throws StorageException; + + abstract void updateObject(T entity, Request request) throws StorageException; + + abstract void removeObject(Class clazz, Request request) throws StorageException; + + T getObject(Class clazz, Request request) throws StorageException { + var objects = getObjects(clazz, request); + if (objects.isEmpty()) { + throw new StorageException("No objects found"); + } + return objects.get(0); + } + +} diff --git a/src/main/java/org/traccar/storage/StorageException.java b/src/main/java/org/traccar/storage/StorageException.java new file mode 100644 index 000000000..6c1e9c2ff --- /dev/null +++ b/src/main/java/org/traccar/storage/StorageException.java @@ -0,0 +1,17 @@ +package org.traccar.storage; + +public class StorageException extends Exception { + + public StorageException(String message) { + super(message); + } + + public StorageException(Throwable cause) { + super(cause); + } + + public StorageException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/src/main/java/org/traccar/storage/StorageName.java b/src/main/java/org/traccar/storage/StorageName.java new file mode 100644 index 000000000..b6fa55e02 --- /dev/null +++ b/src/main/java/org/traccar/storage/StorageName.java @@ -0,0 +1,12 @@ +package org.traccar.storage; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface StorageName { + String value(); +} diff --git a/src/main/java/org/traccar/storage/query/Columns.java b/src/main/java/org/traccar/storage/query/Columns.java new file mode 100644 index 000000000..2053c556f --- /dev/null +++ b/src/main/java/org/traccar/storage/query/Columns.java @@ -0,0 +1,63 @@ +package org.traccar.storage.query; + +import org.traccar.storage.QueryIgnore; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +abstract public class Columns { + + abstract public List getColumns(Class clazz); + + protected List getAllColumns(Class clazz) { + List columns = new LinkedList<>(); + Method[] methods = clazz.getMethods(); + for (Method method : methods) { + if (method.getName().startsWith("set") && method.getParameterTypes().length == 1 + && !method.isAnnotationPresent(QueryIgnore.class)) { + columns.add(method.getName().substring(3).toLowerCase()); + } + } + return columns; + } + + public static class All extends Columns { + @Override + public List getColumns(Class clazz) { + return getAllColumns(clazz); + } + } + + public static class Include extends Columns { + private final List columns; + + public Include(String... columns) { + this.columns = Arrays.stream(columns).collect(Collectors.toList()); + } + + @Override + public List getColumns(Class clazz) { + return columns; + } + } + + public static class Exclude extends Columns { + private final Set columns; + + public Exclude(String... columns) { + this.columns = Arrays.stream(columns).collect(Collectors.toSet()); + } + + @Override + public List getColumns(Class clazz) { + return getAllColumns(clazz).stream() + .filter(column -> !columns.contains(column)) + .collect(Collectors.toList()); + } + } + +} diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java new file mode 100644 index 000000000..50d520bc7 --- /dev/null +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -0,0 +1,83 @@ +package org.traccar.storage.query; + +public interface Condition { + + class Equals implements Condition { + private final String column; + private final String variable; + private final Object value; + + public Equals(String column, String variable, Object value) { + this.column = column; + this.variable = variable; + this.value = value; + } + + public String getColumn() { + return column; + } + + public String getVariable() { + return variable; + } + + public Object getValue() { + return value; + } + } + + class Between implements Condition { + private final String column; + private final String fromVariable; + private final Object fromValue; + private final String toVariable; + private final Object toValue; + + public Between(String column, String fromVariable, Object fromValue, String toVariable, Object toValue) { + this.column = column; + this.fromVariable = fromVariable; + this.fromValue = fromValue; + this.toVariable = toVariable; + this.toValue = toValue; + } + + public String getColumn() { + return column; + } + + public String getFromVariable() { + return fromVariable; + } + + public Object getFromValue() { + return fromValue; + } + + public String getToVariable() { + return toVariable; + } + + public Object getToValue() { + return toValue; + } + } + + class And implements Condition { + private final Condition first; + private final Condition second; + + public And(Condition first, Condition second) { + this.first = first; + this.second = second; + } + + public Condition getFirst() { + return first; + } + + public Condition getSecond() { + return second; + } + } + +} diff --git a/src/main/java/org/traccar/storage/query/Order.java b/src/main/java/org/traccar/storage/query/Order.java new file mode 100644 index 000000000..6852c5ba8 --- /dev/null +++ b/src/main/java/org/traccar/storage/query/Order.java @@ -0,0 +1,25 @@ +package org.traccar.storage.query; + +public class Order { + + private final String column; + private final boolean descending; + + public Order(String column) { + this(false, column); + } + + public Order(boolean descending, String column) { + this.column = column; + this.descending = descending; + } + + public String getColumn() { + return column; + } + + public boolean getDescending() { + return descending; + } + +} diff --git a/src/main/java/org/traccar/storage/query/Request.java b/src/main/java/org/traccar/storage/query/Request.java new file mode 100644 index 000000000..8536cafd0 --- /dev/null +++ b/src/main/java/org/traccar/storage/query/Request.java @@ -0,0 +1,27 @@ +package org.traccar.storage.query; + +public class Request { + + private final Columns columns; + private final Condition condition; + private final Order order; + + public Request(Columns columns, Condition condition, Order order) { + this.columns = columns; + this.condition = condition; + this.order = order; + } + + public Columns getColumns() { + return columns; + } + + public Condition getCondition() { + return condition; + } + + public Order getOrder() { + return order; + } + +} -- cgit v1.2.3 From de110b28ce8adb6ba875d88ede6e8f86dae4dd48 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Feb 2022 17:04:56 -0800 Subject: Fix style issues --- src/main/java/org/traccar/storage/query/Columns.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/storage/query/Columns.java b/src/main/java/org/traccar/storage/query/Columns.java index 2053c556f..1a13665ee 100644 --- a/src/main/java/org/traccar/storage/query/Columns.java +++ b/src/main/java/org/traccar/storage/query/Columns.java @@ -9,9 +9,9 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; -abstract public class Columns { +public abstract class Columns { - abstract public List getColumns(Class clazz); + public abstract List getColumns(Class clazz); protected List getAllColumns(Class clazz) { List columns = new LinkedList<>(); -- cgit v1.2.3 From 1c73bae2e23242673e0a07cdbc2493700f134ceb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Feb 2022 23:34:25 -0800 Subject: New storage implementation --- setup/default.xml | 30 --- src/main/java/org/traccar/MainEventHandler.java | 4 +- .../java/org/traccar/api/BaseObjectResource.java | 7 +- .../org/traccar/api/SecurityRequestFilter.java | 4 +- .../traccar/api/resource/AttributeResource.java | 9 +- .../org/traccar/api/resource/DeviceResource.java | 3 +- .../org/traccar/api/resource/EventResource.java | 6 +- .../org/traccar/api/resource/PasswordResource.java | 6 +- .../traccar/api/resource/PermissionsResource.java | 10 +- .../org/traccar/api/resource/PositionResource.java | 4 +- .../org/traccar/api/resource/ReportResource.java | 28 +-- .../org/traccar/api/resource/ServerResource.java | 6 +- .../org/traccar/api/resource/SessionResource.java | 6 +- .../traccar/api/resource/StatisticsResource.java | 4 +- .../org/traccar/api/resource/UserResource.java | 3 +- .../org/traccar/database/BaseObjectManager.java | 10 +- .../org/traccar/database/ConnectionManager.java | 6 +- .../java/org/traccar/database/DataManager.java | 265 ++++++++------------- .../java/org/traccar/database/DeviceManager.java | 28 +-- .../traccar/database/ExtendedObjectManager.java | 6 +- .../java/org/traccar/database/GroupsManager.java | 4 +- .../org/traccar/database/NotificationManager.java | 4 +- .../org/traccar/database/PermissionsManager.java | 10 +- .../org/traccar/database/SimpleObjectManager.java | 6 +- .../org/traccar/database/StatisticsManager.java | 4 +- .../java/org/traccar/database/UsersManager.java | 9 + .../java/org/traccar/handler/FilterHandler.java | 4 +- src/main/java/org/traccar/model/Attribute.java | 3 + src/main/java/org/traccar/model/Calendar.java | 2 + src/main/java/org/traccar/model/Command.java | 8 + src/main/java/org/traccar/model/Device.java | 7 +- src/main/java/org/traccar/model/Driver.java | 4 + src/main/java/org/traccar/model/Event.java | 3 + src/main/java/org/traccar/model/Geofence.java | 2 + src/main/java/org/traccar/model/Group.java | 3 + src/main/java/org/traccar/model/Maintenance.java | 3 + src/main/java/org/traccar/model/Notification.java | 4 +- src/main/java/org/traccar/model/Order.java | 3 + src/main/java/org/traccar/model/Position.java | 15 +- src/main/java/org/traccar/model/Server.java | 2 + src/main/java/org/traccar/model/Statistics.java | 3 + src/main/java/org/traccar/model/User.java | 2 + src/main/java/org/traccar/reports/Events.java | 6 +- src/main/java/org/traccar/reports/Route.java | 6 +- src/main/java/org/traccar/reports/Stops.java | 8 +- src/main/java/org/traccar/reports/Summary.java | 8 +- src/main/java/org/traccar/reports/Trips.java | 8 +- .../java/org/traccar/storage/DatabaseStorage.java | 71 ++++-- .../java/org/traccar/storage/QueryBuilder.java | 6 +- src/main/java/org/traccar/storage/Storage.java | 15 +- .../java/org/traccar/storage/query/Columns.java | 22 +- .../java/org/traccar/storage/query/Condition.java | 42 +++- src/main/java/org/traccar/storage/query/Limit.java | 15 ++ .../java/org/traccar/storage/query/Request.java | 22 ++ .../java/org/traccar/database/DataManagerTest.java | 81 ------- 55 files changed, 420 insertions(+), 440 deletions(-) create mode 100644 src/main/java/org/traccar/storage/query/Limit.java delete mode 100644 src/test/java/org/traccar/database/DataManagerTest.java diff --git a/setup/default.xml b/setup/default.xml index 0d8133627..a1ba5ca33 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -41,37 +41,7 @@ true true - true ./schema/changelog-master.xml - - - SELECT * FROM tc_users - WHERE email = :email OR login = :email - - - - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime BETWEEN :from AND :to ORDER BY fixTime - - - - SELECT * FROM tc_positions WHERE deviceId = :deviceId AND fixTime <= :time ORDER BY fixTime DESC LIMIT 1 - - - - SELECT tc_positions.* FROM tc_positions INNER JOIN tc_devices ON tc_positions.id = tc_devices.positionid; - - - - UPDATE tc_devices SET positionId = :id WHERE id = :deviceId - - - - SELECT * FROM tc_events WHERE deviceId = :deviceId AND eventTime BETWEEN :from AND :to ORDER BY eventTime - - - - SELECT * FROM tc_statistics WHERE captureTime BETWEEN :from AND :to ORDER BY captureTime - 5001 5002 diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 4889f6a2e..a3f6f4105 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -27,8 +27,8 @@ import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.model.Position; +import org.traccar.storage.StorageException; -import java.sql.SQLException; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; @@ -57,7 +57,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { Position position = (Position) msg; try { Context.getDeviceManager().updateLatestPosition(position); - } catch (SQLException error) { + } catch (StorageException error) { LOGGER.warn("Failed to update device", error); } diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 71f3939cb..22756f62a 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -41,6 +41,7 @@ import org.traccar.model.Group; import org.traccar.model.GroupedModel; import org.traccar.model.ScheduledModel; import org.traccar.model.User; +import org.traccar.storage.StorageException; public abstract class BaseObjectResource extends BaseResource { @@ -87,7 +88,7 @@ public abstract class BaseObjectResource extends BaseResour } @POST - public Response add(T entity) throws SQLException { + public Response add(T entity) throws StorageException { Context.getPermissionsManager().checkReadonly(getUserId()); if (baseClass.equals(Device.class)) { Context.getPermissionsManager().checkDeviceReadonly(getUserId()); @@ -120,7 +121,7 @@ public abstract class BaseObjectResource extends BaseResour @Path("{id}") @PUT - public Response update(T entity) throws SQLException { + public Response update(T entity) throws StorageException { Context.getPermissionsManager().checkReadonly(getUserId()); if (baseClass.equals(Device.class)) { Context.getPermissionsManager().checkDeviceReadonly(getUserId()); @@ -150,7 +151,7 @@ public abstract class BaseObjectResource extends BaseResour @Path("{id}") @DELETE - public Response remove(@PathParam("id") long id) throws SQLException { + public Response remove(@PathParam("id") long id) throws StorageException { Context.getPermissionsManager().checkReadonly(getUserId()); if (baseClass.equals(Device.class)) { Context.getPermissionsManager().checkDeviceReadonly(getUserId()); diff --git a/src/main/java/org/traccar/api/SecurityRequestFilter.java b/src/main/java/org/traccar/api/SecurityRequestFilter.java index 33b6b37df..6b190be9f 100644 --- a/src/main/java/org/traccar/api/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/SecurityRequestFilter.java @@ -23,6 +23,7 @@ import org.traccar.api.resource.SessionResource; import org.traccar.database.StatisticsManager; import org.traccar.helper.DataConverter; import org.traccar.model.User; +import org.traccar.storage.StorageException; import javax.annotation.security.PermitAll; import javax.servlet.http.HttpServletRequest; @@ -34,7 +35,6 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; -import java.sql.SQLException; public class SecurityRequestFilter implements ContainerRequestFilter { @@ -82,7 +82,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { Main.getInjector().getInstance(StatisticsManager.class).registerRequest(user.getId()); securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); } - } catch (SQLException e) { + } catch (StorageException e) { throw new WebApplicationException(e); } diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index de69d871c..d2dc28903 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -16,8 +16,6 @@ */ package org.traccar.api.resource; -import java.sql.SQLException; - import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.POST; @@ -34,6 +32,7 @@ import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Attribute; import org.traccar.model.Position; import org.traccar.handler.ComputedAttributesHandler; +import org.traccar.storage.StorageException; @Path("attributes/computed") @Produces(MediaType.APPLICATION_JSON) @@ -75,21 +74,21 @@ public class AttributeResource extends ExtendedObjectResource { } @POST - public Response add(Attribute entity) throws SQLException { + public Response add(Attribute entity) throws StorageException { Context.getPermissionsManager().checkAdmin(getUserId()); return super.add(entity); } @Path("{id}") @PUT - public Response update(Attribute entity) throws SQLException { + public Response update(Attribute entity) throws StorageException { Context.getPermissionsManager().checkAdmin(getUserId()); return super.update(entity); } @Path("{id}") @DELETE - public Response remove(@PathParam("id") long id) throws SQLException { + public Response remove(@PathParam("id") long id) throws StorageException { Context.getPermissionsManager().checkAdmin(getUserId()); return super.remove(id); } diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 7006cdb84..9436b59f6 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -21,6 +21,7 @@ import org.traccar.database.DeviceManager; import org.traccar.helper.LogAction; import org.traccar.model.Device; import org.traccar.model.DeviceAccumulators; +import org.traccar.storage.StorageException; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -87,7 +88,7 @@ public class DeviceResource extends BaseObjectResource { @Path("{id}/accumulators") @PUT - public Response updateAccumulators(DeviceAccumulators entity) throws SQLException { + public Response updateAccumulators(DeviceAccumulators entity) throws StorageException { if (!Context.getPermissionsManager().getUserAdmin(getUserId())) { Context.getPermissionsManager().checkManager(getUserId()); Context.getPermissionsManager().checkPermission(Device.class, getUserId(), entity.getDeviceId()); diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index 34e4a94ce..354d96e4f 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -15,8 +15,6 @@ */ package org.traccar.api.resource; -import java.sql.SQLException; - import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -31,16 +29,16 @@ import org.traccar.api.BaseResource; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Maintenance; +import org.traccar.storage.StorageException; @Path("events") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) - public class EventResource extends BaseResource { @Path("{id}") @GET - public Event get(@PathParam("id") long id) throws SQLException { + public Event get(@PathParam("id") long id) throws StorageException { Event event = Context.getDataManager().getObject(Event.class, id); if (event == null) { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 1868a6191..0642ff3cc 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -21,6 +21,7 @@ import org.traccar.api.BaseResource; import org.traccar.model.User; import org.traccar.notification.NotificationMessage; import org.traccar.notification.TextTemplateFormatter; +import org.traccar.storage.StorageException; import javax.annotation.security.PermitAll; import javax.mail.MessagingException; @@ -31,7 +32,6 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.sql.SQLException; import java.util.UUID; @Path("password") @@ -44,7 +44,7 @@ public class PasswordResource extends BaseResource { @Path("reset") @PermitAll @POST - public Response reset(@FormParam("email") String email) throws SQLException, MessagingException { + public Response reset(@FormParam("email") String email) throws StorageException, MessagingException { for (long userId : Context.getUsersManager().getAllItems()) { User user = Context.getUsersManager().getById(userId); if (email.equals(user.getEmail())) { @@ -66,7 +66,7 @@ public class PasswordResource extends BaseResource { @PermitAll @POST public Response update( - @FormParam("token") String token, @FormParam("password") String password) throws SQLException { + @FormParam("token") String token, @FormParam("password") String password) throws StorageException { for (long userId : Context.getUsersManager().getAllItems()) { User user = Context.getUsersManager().getById(userId); if (token.equals(user.getString(PASSWORD_RESET_TOKEN))) { diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 54d3964b6..7def38919 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -16,7 +16,6 @@ */ package org.traccar.api.resource; -import java.sql.SQLException; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -37,6 +36,7 @@ import org.traccar.helper.LogAction; import org.traccar.model.Device; import org.traccar.model.Permission; import org.traccar.model.User; +import org.traccar.storage.StorageException; @Path("permissions") @Produces(MediaType.APPLICATION_JSON) @@ -71,7 +71,7 @@ public class PermissionsResource extends BaseResource { @Path("bulk") @POST - public Response add(List> entities) throws SQLException, ClassNotFoundException { + public Response add(List> entities) throws StorageException, ClassNotFoundException { Context.getPermissionsManager().checkReadonly(getUserId()); checkPermissionTypes(entities); for (LinkedHashMap entity: entities) { @@ -89,13 +89,13 @@ public class PermissionsResource extends BaseResource { } @POST - public Response add(LinkedHashMap entity) throws SQLException, ClassNotFoundException { + public Response add(LinkedHashMap entity) throws StorageException, ClassNotFoundException { return add(Collections.singletonList(entity)); } @DELETE @Path("bulk") - public Response remove(List> entities) throws SQLException, ClassNotFoundException { + public Response remove(List> entities) throws StorageException, ClassNotFoundException { Context.getPermissionsManager().checkReadonly(getUserId()); checkPermissionTypes(entities); for (LinkedHashMap entity: entities) { @@ -113,7 +113,7 @@ public class PermissionsResource extends BaseResource { } @DELETE - public Response remove(LinkedHashMap entity) throws SQLException, ClassNotFoundException { + public Response remove(LinkedHashMap entity) throws StorageException, ClassNotFoundException { return remove(Collections.singletonList(entity)); } diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 53157197b..511032402 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -18,6 +18,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.Position; +import org.traccar.storage.StorageException; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -25,7 +26,6 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -41,7 +41,7 @@ public class PositionResource extends BaseResource { public Collection getJson( @QueryParam("deviceId") long deviceId, @QueryParam("id") List positionIds, @QueryParam("from") Date from, @QueryParam("to") Date to) - throws SQLException { + throws StorageException { if (!positionIds.isEmpty()) { ArrayList positions = new ArrayList<>(); for (Long positionId : positionIds) { diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 23ffaf54c..03df0d03a 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -18,7 +18,6 @@ package org.traccar.api.resource; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.sql.SQLException; import java.util.Collection; import java.util.Date; import java.util.List; @@ -51,6 +50,7 @@ import org.traccar.reports.model.SummaryReport; import org.traccar.reports.model.TripReport; import org.traccar.reports.Route; import org.traccar.reports.Stops; +import org.traccar.storage.StorageException; @Path("reports") @Produces(MediaType.APPLICATION_JSON) @@ -63,11 +63,11 @@ public class ReportResource extends BaseResource { private static final String CONTENT_DISPOSITION_VALUE_XLSX = "attachment; filename=report.xlsx"; private interface ReportExecutor { - void execute(ByteArrayOutputStream stream) throws SQLException, IOException; + void execute(ByteArrayOutputStream stream) throws StorageException, IOException; } private Response executeReport( - long userId, boolean mail, ReportExecutor executor) throws SQLException, IOException { + long userId, boolean mail, ReportExecutor executor) throws StorageException, IOException { final ByteArrayOutputStream stream = new ByteArrayOutputStream(); if (mail) { new Thread(() -> { @@ -82,7 +82,7 @@ public class ReportResource extends BaseResource { Context.getMailManager().sendMessage( userId, "Report", "The report is in the attachment.", attachment); - } catch (SQLException | IOException | MessagingException e) { + } catch (StorageException | IOException | MessagingException e) { LOGGER.warn("Report failed", e); } }).start(); @@ -98,7 +98,7 @@ public class ReportResource extends BaseResource { @GET public Collection getRoute( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws SQLException { + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { Context.getPermissionsManager().checkDisableReports(getUserId()); LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); return Route.getObjects(getUserId(), deviceIds, groupIds, from, to); @@ -110,7 +110,7 @@ public class ReportResource extends BaseResource { public Response getRouteExcel( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws SQLException, IOException { + throws StorageException, IOException { Context.getPermissionsManager().checkDisableReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); @@ -123,7 +123,7 @@ public class ReportResource extends BaseResource { public Collection getEvents( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("type") final List types, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws SQLException { + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { Context.getPermissionsManager().checkDisableReports(getUserId()); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); return Events.getObjects(getUserId(), deviceIds, groupIds, types, from, to); @@ -136,7 +136,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws SQLException, IOException { + throws StorageException, IOException { Context.getPermissionsManager().checkDisableReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); @@ -149,7 +149,7 @@ public class ReportResource extends BaseResource { public Collection getSummary( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily) - throws SQLException { + throws StorageException { Context.getPermissionsManager().checkDisableReports(getUserId()); LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); return Summary.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); @@ -162,7 +162,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily, @QueryParam("mail") boolean mail) - throws SQLException, IOException { + throws StorageException, IOException { Context.getPermissionsManager().checkDisableReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); @@ -175,7 +175,7 @@ public class ReportResource extends BaseResource { @Produces(MediaType.APPLICATION_JSON) public Collection getTrips( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws SQLException { + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { Context.getPermissionsManager().checkDisableReports(getUserId()); LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); return Trips.getObjects(getUserId(), deviceIds, groupIds, from, to); @@ -187,7 +187,7 @@ public class ReportResource extends BaseResource { public Response getTripsExcel( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws SQLException, IOException { + throws StorageException, IOException { Context.getPermissionsManager().checkDisableReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); @@ -200,7 +200,7 @@ public class ReportResource extends BaseResource { @Produces(MediaType.APPLICATION_JSON) public Collection getStops( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws SQLException { + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { Context.getPermissionsManager().checkDisableReports(getUserId()); LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); return Stops.getObjects(getUserId(), deviceIds, groupIds, from, to); @@ -212,7 +212,7 @@ public class ReportResource extends BaseResource { public Response getStopsExcel( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws SQLException, IOException { + throws StorageException, IOException { Context.getPermissionsManager().checkDisableReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 91488afff..8096c66fa 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -19,6 +19,7 @@ import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Server; +import org.traccar.storage.StorageException; import javax.annotation.security.PermitAll; import javax.ws.rs.Consumes; @@ -29,7 +30,6 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.sql.SQLException; @Path("server") @Produces(MediaType.APPLICATION_JSON) @@ -38,7 +38,7 @@ public class ServerResource extends BaseResource { @PermitAll @GET - public Server get(@QueryParam("force") boolean force) throws SQLException { + public Server get(@QueryParam("force") boolean force) throws StorageException { if (force) { return Context.getDataManager().getServer(); } else { @@ -47,7 +47,7 @@ public class ServerResource extends BaseResource { } @PUT - public Response update(Server entity) throws SQLException { + public Response update(Server entity) throws StorageException { Context.getPermissionsManager().checkAdmin(getUserId()); Context.getPermissionsManager().updateServer(entity); LogAction.edit(getUserId(), entity); diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 60ce5490a..8422e0b49 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -21,6 +21,7 @@ import org.traccar.helper.DataConverter; import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; import org.traccar.model.User; +import org.traccar.storage.StorageException; import javax.annotation.security.PermitAll; import javax.servlet.http.Cookie; @@ -40,7 +41,6 @@ import javax.ws.rs.core.Response; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; -import java.sql.SQLException; @Path("session") @Produces(MediaType.APPLICATION_JSON) @@ -56,7 +56,7 @@ public class SessionResource extends BaseResource { @PermitAll @GET - public User get(@QueryParam("token") String token) throws SQLException, UnsupportedEncodingException { + public User get(@QueryParam("token") String token) throws StorageException, UnsupportedEncodingException { if (token != null) { User user = Context.getUsersManager().getUserByToken(token); @@ -107,7 +107,7 @@ public class SessionResource extends BaseResource { @PermitAll @POST public User add( - @FormParam("email") String email, @FormParam("password") String password) throws SQLException { + @FormParam("email") String email, @FormParam("password") String password) throws StorageException { User user = Context.getPermissionsManager().login(email, password); if (user != null) { request.getSession().setAttribute(USER_ID_KEY, user.getId()); diff --git a/src/main/java/org/traccar/api/resource/StatisticsResource.java b/src/main/java/org/traccar/api/resource/StatisticsResource.java index 58073e7d1..5c0734877 100644 --- a/src/main/java/org/traccar/api/resource/StatisticsResource.java +++ b/src/main/java/org/traccar/api/resource/StatisticsResource.java @@ -18,6 +18,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.Statistics; +import org.traccar.storage.StorageException; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -25,7 +26,6 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; -import java.sql.SQLException; import java.util.Collection; import java.util.Date; @@ -36,7 +36,7 @@ public class StatisticsResource extends BaseResource { @GET public Collection get( - @QueryParam("from") Date from, @QueryParam("to") Date to) throws SQLException { + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { Context.getPermissionsManager().checkAdmin(getUserId()); return Context.getDataManager().getStatistics(from, to); } diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index d54cc2382..83bb8fd0b 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -22,6 +22,7 @@ import org.traccar.database.UsersManager; import org.traccar.helper.LogAction; import org.traccar.model.ManagedUser; import org.traccar.model.User; +import org.traccar.storage.StorageException; import javax.annotation.security.PermitAll; import javax.ws.rs.Consumes; @@ -67,7 +68,7 @@ public class UserResource extends BaseObjectResource { @Override @PermitAll @POST - public Response add(User entity) throws SQLException { + public Response add(User entity) throws StorageException { if (!Context.getPermissionsManager().getUserAdmin(getUserId())) { Context.getPermissionsManager().checkUserUpdate(getUserId(), new User(), entity); if (Context.getPermissionsManager().getUserManager(getUserId())) { diff --git a/src/main/java/org/traccar/database/BaseObjectManager.java b/src/main/java/org/traccar/database/BaseObjectManager.java index be6310033..dd8b3bae4 100644 --- a/src/main/java/org/traccar/database/BaseObjectManager.java +++ b/src/main/java/org/traccar/database/BaseObjectManager.java @@ -16,7 +16,6 @@ */ package org.traccar.database; -import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; @@ -29,6 +28,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.BaseModel; +import org.traccar.storage.StorageException; public class BaseObjectManager { @@ -102,7 +102,7 @@ public class BaseObjectManager { removeCachedItem(cachedItemId); } } - } catch (SQLException error) { + } catch (StorageException error) { LOGGER.warn("Error refreshing items", error); } finally { writeUnlock(); @@ -119,7 +119,7 @@ public class BaseObjectManager { } } - public void addItem(T item) throws SQLException { + public void addItem(T item) throws StorageException { dataManager.addObject(item); addNewItem(item); } @@ -133,7 +133,7 @@ public class BaseObjectManager { } } - public void updateItem(T item) throws SQLException { + public void updateItem(T item) throws StorageException { dataManager.updateObject(item); updateCachedItem(item); } @@ -147,7 +147,7 @@ public class BaseObjectManager { } } - public void removeItem(long itemId) throws SQLException { + public void removeItem(long itemId) throws StorageException { BaseModel item = getById(itemId); if (item != null) { dataManager.removeObject(baseClass, itemId); diff --git a/src/main/java/org/traccar/database/ConnectionManager.java b/src/main/java/org/traccar/database/ConnectionManager.java index e12d44612..359061f00 100644 --- a/src/main/java/org/traccar/database/ConnectionManager.java +++ b/src/main/java/org/traccar/database/ConnectionManager.java @@ -30,9 +30,9 @@ import org.traccar.model.Device; import org.traccar.model.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.storage.StorageException; import java.net.SocketAddress; -import java.sql.SQLException; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -127,8 +127,8 @@ public class ConnectionManager { try { Context.getDeviceManager().updateDeviceStatus(device); - } catch (SQLException error) { - LOGGER.warn("Update device status error", error); + } catch (StorageException e) { + LOGGER.warn("Update device status error", e); } updateDevice(device); diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 199167419..303b8e033 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,15 +41,20 @@ import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; -import org.traccar.model.Order; import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.Statistics; import org.traccar.model.User; +import org.traccar.storage.DatabaseStorage; import org.traccar.storage.QueryBuilder; -import org.traccar.storage.QueryExtended; -import org.traccar.storage.QueryIgnore; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Limit; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; import javax.sql.DataSource; import java.beans.Introspector; @@ -57,11 +62,10 @@ import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.sql.SQLException; -import java.util.Arrays; import java.util.Collection; import java.util.Date; -import java.util.HashSet; -import java.util.Set; +import java.util.LinkedList; +import java.util.List; public class DataManager { @@ -81,6 +85,8 @@ public class DataManager { return dataSource; } + private final Storage storage; + private boolean generateQueries; private final boolean forceLdap; @@ -92,6 +98,8 @@ public class DataManager { initDatabase(); initDatabaseSchema(); + + storage = new DatabaseStorage(dataSource); } private void initDatabase() throws Exception { @@ -134,58 +142,6 @@ public class DataManager { dataSource = new HikariDataSource(hikariConfig); } - public static String constructObjectQuery(String action, Class clazz, boolean extended) { - switch (action) { - case ACTION_INSERT: - case ACTION_UPDATE: - StringBuilder result = new StringBuilder(); - StringBuilder fields = new StringBuilder(); - StringBuilder values = new StringBuilder(); - - Set methods = new HashSet<>(Arrays.asList(clazz.getMethods())); - methods.removeAll(Arrays.asList(Object.class.getMethods())); - methods.removeAll(Arrays.asList(BaseModel.class.getMethods())); - for (Method method : methods) { - boolean skip; - if (extended) { - skip = !method.isAnnotationPresent(QueryExtended.class); - } else { - skip = method.isAnnotationPresent(QueryIgnore.class) - || method.isAnnotationPresent(QueryExtended.class) && !action.equals(ACTION_INSERT); - } - if (!skip && method.getName().startsWith("get") && method.getParameterTypes().length == 0) { - String name = Introspector.decapitalize(method.getName().substring(3)); - if (action.equals(ACTION_INSERT)) { - fields.append(name).append(", "); - values.append(":").append(name).append(", "); - } else { - fields.append(name).append(" = :").append(name).append(", "); - } - } - } - fields.setLength(fields.length() - 2); - if (action.equals(ACTION_INSERT)) { - values.setLength(values.length() - 2); - result.append("INSERT INTO ").append(getObjectsTableName(clazz)).append(" ("); - result.append(fields).append(") "); - result.append("VALUES (").append(values).append(")"); - } else { - result.append("UPDATE ").append(getObjectsTableName(clazz)).append(" SET "); - result.append(fields); - result.append(" WHERE id = :id"); - } - return result.toString(); - case ACTION_SELECT_ALL: - return "SELECT * FROM " + getObjectsTableName(clazz); - case ACTION_SELECT: - return "SELECT * FROM " + getObjectsTableName(clazz) + " WHERE id = :id"; - case ACTION_DELETE: - return "DELETE FROM " + getObjectsTableName(clazz) + " WHERE id = :id"; - default: - throw new IllegalArgumentException("Unknown action"); - } - } - public static String constructPermissionQuery(String action, Class owner, Class property) { switch (action) { case ACTION_SELECT_ALL: @@ -204,39 +160,6 @@ public class DataManager { } } - private String getQuery(String key) { - String query = config.getString(key); - if (query == null) { - LOGGER.info("Query not provided: " + key); - } - return query; - } - - public String getQuery(String action, Class clazz) { - return getQuery(action, clazz, false); - } - - public String getQuery(String action, Class clazz, boolean extended) { - String queryName; - if (action.equals(ACTION_SELECT_ALL)) { - queryName = "database.select" + clazz.getSimpleName() + "s"; - } else { - queryName = "database." + action.toLowerCase() + clazz.getSimpleName(); - if (extended) { - queryName += "Extended"; - } - } - String query = config.getString(queryName); - if (query == null) { - if (generateQueries) { - query = constructObjectQuery(action, clazz, extended); - } else { - LOGGER.info("Query not provided: " + queryName); - } - } - return query; - } - public String getQuery(String action, Class owner, Class property) { String queryName; switch (action) { @@ -302,10 +225,12 @@ public class DataManager { } } - public User login(String email, String password) throws SQLException { - User user = QueryBuilder.create(dataSource, getQuery("database.loginUser")) - .setString("email", email.trim()) - .executeQuerySingle(User.class); + public User login(String email, String password) throws StorageException { + User user = storage.getObject(User.class, new Request( + new Columns.Include("id", "login", "hashedPassword", "salt"), + new Condition.Or( + new Condition.Equals("email", "email", email.trim()), + new Condition.Equals("login", "email")))); LdapProvider ldapProvider = Context.getLdapProvider(); if (user != null) { if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) @@ -322,57 +247,75 @@ public class DataManager { return null; } - public void updateDeviceStatus(Device device) throws SQLException { - QueryBuilder.create(dataSource, getQuery(ACTION_UPDATE, Device.class, true)) - .setObject(device) - .executeUpdate(); + public void updateUserPassword(User user) throws StorageException { + storage.updateObject(user, new Request( + new Columns.Include("hashedPassword", "salt"), + new Condition.Equals("id", "id"))); } - public Collection getPositions(long deviceId, Date from, Date to) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectPositions")) - .setLong("deviceId", deviceId) - .setDate("from", from) - .setDate("to", to) - .executeQuery(Position.class); + public void updateDeviceStatus(Device device) throws StorageException { + storage.updateObject(device, new Request( + new Columns.Include("lastUpdate"), + new Condition.Equals("id", "id"))); } - public Position getPrecedingPosition(long deviceId, Date date) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectPrecedingPosition")) - .setLong("deviceId", deviceId) - .setDate("time", date) - .executeQuerySingle(Position.class); + public Collection getPositions(long deviceId, Date from, Date to) throws StorageException { + return storage.getObjects(Position.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Between("fixTime", "from", from, "to", to)), + new Order("fixTime"))); } - public void updateLatestPosition(Position position) throws SQLException { - QueryBuilder.create(dataSource, getQuery("database.updateLatestPosition")) - .setDate("now", new Date()) - .setObject(position) - .executeUpdate(); + public Position getPrecedingPosition(long deviceId, Date date) throws StorageException { + return storage.getObject(Position.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Compare("fixTime", "<=", "time", date)), + new Order(true, "fixTime"), + new Limit(1))); } - public Collection getLatestPositions() throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectLatestPositions")) - .executeQuery(Position.class); + public void updateLatestPosition(Position position) throws StorageException { + Device device = new Device(); + device.setId(position.getDeviceId()); + device.setPositionId(position.getId()); + storage.updateObject(device, new Request( + new Columns.Include("positionId"), + new Condition.Equals("id", "id"))); + } + + public Collection getLatestPositions() throws StorageException { + List positions = new LinkedList<>(); + List devices = storage.getObjects(Device.class, new Request(new Columns.Include("positionId"))); + for (Device device : devices) { + positions.addAll(storage.getObjects(Position.class, new Request( + new Columns.All(), + new Condition.Equals("id", "id", device.getPositionId())))); + } + return positions; } - public Server getServer() throws SQLException { - return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, Server.class)) - .executeQuerySingle(Server.class); + public Server getServer() throws StorageException { + return storage.getObject(Server.class, new Request(new Columns.All())); } - public Collection getEvents(long deviceId, Date from, Date to) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectEvents")) - .setLong("deviceId", deviceId) - .setDate("from", from) - .setDate("to", to) - .executeQuery(Event.class); + public Collection getEvents(long deviceId, Date from, Date to) throws StorageException { + return storage.getObjects(Event.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Between("eventTime", "from", from, "to", to)), + new Order("eventTime"))); } - public Collection getStatistics(Date from, Date to) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectStatistics")) - .setDate("from", from) - .setDate("to", to) - .executeQuery(Statistics.class); + public Collection getStatistics(Date from, Date to) throws StorageException { + return storage.getObjects(Statistics.class, new Request( + new Columns.All(), + new Condition.Between("captureTime", "from", from, "to", to), + new Order("captureTime"))); } public static Class getClassByName(String name) throws ClassNotFoundException { @@ -400,7 +343,7 @@ public class DataManager { case "notification": return Notification.class; case "order": - return Order.class; + return org.traccar.model.Order.class; default: throw new ClassNotFoundException(); } @@ -412,51 +355,49 @@ public class DataManager { } public Collection getPermissions(Class owner, Class property) - throws SQLException, ClassNotFoundException { - return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, owner, property)) - .executePermissionsQuery(); + throws StorageException, ClassNotFoundException { + try { + return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, owner, property)) + .executePermissionsQuery(); + } catch (SQLException e) { + throw new StorageException(e); + } } public void linkObject(Class owner, long ownerId, Class property, long propertyId, boolean link) - throws SQLException { + throws StorageException { + try { QueryBuilder.create(dataSource, getQuery(link ? ACTION_INSERT : ACTION_DELETE, owner, property)) .setLong(makeNameId(owner), ownerId) .setLong(makeNameId(property), propertyId) .executeUpdate(); + } catch (SQLException e) { + throw new StorageException(e); + } } - public T getObject(Class clazz, long entityId) throws SQLException { - return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT, clazz)) - .setLong("id", entityId) - .executeQuerySingle(clazz); + public T getObject(Class clazz, long entityId) throws StorageException { + return storage.getObject(clazz, new Request( + new Columns.All(), + new Condition.Equals("id", "id", entityId))); } - public Collection getObjects(Class clazz) throws SQLException { - return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, clazz)) - .executeQuery(clazz); + public Collection getObjects(Class clazz) throws StorageException { + return storage.getObjects(clazz, new Request(new Columns.All())); } - public void addObject(BaseModel entity) throws SQLException { - entity.setId(QueryBuilder.create(dataSource, getQuery(ACTION_INSERT, entity.getClass()), true) - .setObject(entity) - .executeUpdate()); + public void addObject(BaseModel entity) throws StorageException { + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); } - public void updateObject(BaseModel entity) throws SQLException { - QueryBuilder.create(dataSource, getQuery(ACTION_UPDATE, entity.getClass())) - .setObject(entity) - .executeUpdate(); - if (entity instanceof User && ((User) entity).getHashedPassword() != null) { - QueryBuilder.create(dataSource, getQuery(ACTION_UPDATE, User.class, true)) - .setObject(entity) - .executeUpdate(); - } + public void updateObject(BaseModel entity) throws StorageException { + storage.updateObject(entity, new Request( + new Columns.Exclude("id"), + new Condition.Equals("id", "id"))); } - public void removeObject(Class clazz, long entityId) throws SQLException { - QueryBuilder.create(dataSource, getQuery(ACTION_DELETE, clazz)) - .setLong("id", entityId) - .executeUpdate(); + public void removeObject(Class clazz, long entityId) throws StorageException { + storage.removeObject(clazz, new Request(new Condition.Equals("id", "id", entityId))); } } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index c8a99274c..40591e869 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -37,6 +37,7 @@ import org.traccar.model.DeviceAccumulators; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; +import org.traccar.storage.StorageException; public class DeviceManager extends BaseObjectManager implements IdentityManager, ManagableObjects { @@ -94,13 +95,13 @@ public class DeviceManager extends BaseObjectManager implements Identity } return device.getId(); - } catch (SQLException e) { + } catch (StorageException e) { LOGGER.warn("Automatic device registration error", e); return 0; } } - public void updateDeviceCache(boolean force) throws SQLException { + public void updateDeviceCache(boolean force) { long lastUpdate = devicesLastUpdate.get(); if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) && devicesLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { @@ -144,24 +145,11 @@ public class DeviceManager extends BaseObjectManager implements Identity return defaultPassword; } - public Device getDeviceByPhone(String phone) { - try { - readLock(); - return devicesByPhone.get(phone); - } finally { - readUnlock(); - } - } - @Override public Set getAllItems() { Set result = super.getAllItems(); if (result.isEmpty()) { - try { - updateDeviceCache(true); - } catch (SQLException e) { - LOGGER.warn("Update device cache error", e); - } + updateDeviceCache(true); result = super.getAllItems(); } return result; @@ -309,7 +297,7 @@ public class DeviceManager extends BaseObjectManager implements Identity positions.remove(deviceId); } - public void updateDeviceStatus(Device device) throws SQLException { + public void updateDeviceStatus(Device device) throws StorageException { getDataManager().updateDeviceStatus(device); Device cachedDevice = getById(device.getId()); if (cachedDevice != null) { @@ -323,7 +311,7 @@ public class DeviceManager extends BaseObjectManager implements Identity for (Position position : getDataManager().getLatestPositions()) { positions.put(position.getDeviceId(), position); } - } catch (SQLException error) { + } catch (StorageException error) { LOGGER.warn("Load latest positions error", error); } } @@ -334,7 +322,7 @@ public class DeviceManager extends BaseObjectManager implements Identity return lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) >= 0; } - public void updateLatestPosition(Position position) throws SQLException { + public void updateLatestPosition(Position position) throws StorageException { if (isLatestPosition(position)) { @@ -451,7 +439,7 @@ public class DeviceManager extends BaseObjectManager implements Identity return result; } - public void resetDeviceAccumulators(DeviceAccumulators deviceAccumulators) throws SQLException { + public void resetDeviceAccumulators(DeviceAccumulators deviceAccumulators) throws StorageException { Position last = positions.get(deviceAccumulators.getDeviceId()); if (last != null) { if (deviceAccumulators.getTotalDistance() != null) { diff --git a/src/main/java/org/traccar/database/ExtendedObjectManager.java b/src/main/java/org/traccar/database/ExtendedObjectManager.java index 93e5820fb..006ed47b2 100644 --- a/src/main/java/org/traccar/database/ExtendedObjectManager.java +++ b/src/main/java/org/traccar/database/ExtendedObjectManager.java @@ -16,7 +16,6 @@ */ package org.traccar.database; -import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; import java.util.Map; @@ -30,6 +29,7 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.BaseModel; +import org.traccar.storage.StorageException; public abstract class ExtendedObjectManager extends SimpleObjectManager { @@ -87,7 +87,7 @@ public abstract class ExtendedObjectManager extends SimpleO } @Override - public void removeItem(long itemId) throws SQLException { + public void removeItem(long itemId) throws StorageException { super.removeItem(itemId); refreshExtendedPermissions(); } @@ -133,7 +133,7 @@ public abstract class ExtendedObjectManager extends SimpleO } } - } catch (SQLException | ClassNotFoundException error) { + } catch (StorageException | ClassNotFoundException error) { LOGGER.warn("Refresh permissions error", error); } finally { writeUnlock(); diff --git a/src/main/java/org/traccar/database/GroupsManager.java b/src/main/java/org/traccar/database/GroupsManager.java index c35f35f93..dafddc0cc 100644 --- a/src/main/java/org/traccar/database/GroupsManager.java +++ b/src/main/java/org/traccar/database/GroupsManager.java @@ -16,12 +16,12 @@ */ package org.traccar.database; -import java.sql.SQLException; import java.util.HashSet; import java.util.Set; import org.traccar.Context; import org.traccar.model.Group; +import org.traccar.storage.StorageException; public class GroupsManager extends BaseObjectManager implements ManagableObjects { @@ -57,7 +57,7 @@ public class GroupsManager extends BaseObjectManager implements Managable } @Override - public void updateItem(Group group) throws SQLException { + public void updateItem(Group group) throws StorageException { checkGroupCycles(group); super.updateItem(group); } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 9f9a83cd2..f358b1d4d 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -18,7 +18,6 @@ package org.traccar.database; import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import java.sql.SQLException; import java.util.Arrays; import java.util.Date; import java.util.HashSet; @@ -36,6 +35,7 @@ import org.traccar.model.Event; import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.Typed; +import org.traccar.storage.StorageException; public class NotificationManager extends ExtendedObjectManager { @@ -66,7 +66,7 @@ public class NotificationManager extends ExtendedObjectManager { public void updateEvent(Event event, Position position) { try { getDataManager().addObject(event); - } catch (SQLException error) { + } catch (StorageException error) { LOGGER.warn("Event save error", error); } diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index ab841a521..2bb808033 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -33,8 +33,8 @@ import org.traccar.model.Order; import org.traccar.model.Permission; import org.traccar.model.Server; import org.traccar.model.User; +import org.traccar.storage.StorageException; -import java.sql.SQLException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -156,7 +156,7 @@ public class PermissionsManager { public void refreshServer() { try { server = dataManager.getServer(); - } catch (SQLException error) { + } catch (StorageException error) { LOGGER.warn("Refresh server config error", error); } } @@ -193,7 +193,7 @@ public class PermissionsManager { } } - } catch (SQLException | ClassNotFoundException error) { + } catch (StorageException | ClassNotFoundException error) { LOGGER.warn("Refresh device permissions error", error); } @@ -499,12 +499,12 @@ public class PermissionsManager { return server; } - public void updateServer(Server server) throws SQLException { + public void updateServer(Server server) throws StorageException { dataManager.updateObject(server); this.server = server; } - public User login(String email, String password) throws SQLException { + public User login(String email, String password) throws StorageException { User user = dataManager.login(email, password); if (user != null) { checkUserEnabled(user.getId()); diff --git a/src/main/java/org/traccar/database/SimpleObjectManager.java b/src/main/java/org/traccar/database/SimpleObjectManager.java index eb8284d4e..78701720f 100644 --- a/src/main/java/org/traccar/database/SimpleObjectManager.java +++ b/src/main/java/org/traccar/database/SimpleObjectManager.java @@ -16,7 +16,6 @@ */ package org.traccar.database; -import java.sql.SQLException; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -28,6 +27,7 @@ import org.traccar.Context; import org.traccar.model.BaseModel; import org.traccar.model.Permission; import org.traccar.model.User; +import org.traccar.storage.StorageException; public abstract class SimpleObjectManager extends BaseObjectManager implements ManagableObjects { @@ -83,7 +83,7 @@ public abstract class SimpleObjectManager extends BaseObjec Set items = userItems.computeIfAbsent(permission.getOwnerId(), key -> new HashSet<>()); items.add(permission.getPropertyId()); } - } catch (SQLException | ClassNotFoundException error) { + } catch (StorageException | ClassNotFoundException error) { LOGGER.warn("Error getting permissions", error); } finally { writeUnlock(); @@ -92,7 +92,7 @@ public abstract class SimpleObjectManager extends BaseObjec } @Override - public void removeItem(long itemId) throws SQLException { + public void removeItem(long itemId) throws StorageException { super.removeItem(itemId); refreshUserItems(); } diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index 4ad6d9d5c..3579ce7a5 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -23,12 +23,12 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.DateUtil; import org.traccar.model.Statistics; +import org.traccar.storage.StorageException; import javax.inject.Inject; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Form; -import java.sql.SQLException; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -106,7 +106,7 @@ public class StatisticsManager { try { dataManager.addObject(statistics); - } catch (SQLException e) { + } catch (StorageException e) { LOGGER.warn("Error saving statistics", e); } diff --git a/src/main/java/org/traccar/database/UsersManager.java b/src/main/java/org/traccar/database/UsersManager.java index b741a85b6..31759dc8b 100644 --- a/src/main/java/org/traccar/database/UsersManager.java +++ b/src/main/java/org/traccar/database/UsersManager.java @@ -21,6 +21,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.traccar.model.User; +import org.traccar.storage.StorageException; public class UsersManager extends SimpleObjectManager { @@ -58,6 +59,14 @@ public class UsersManager extends SimpleObjectManager { } } + @Override + public void updateItem(User user) throws StorageException { + if (user.getHashedPassword() != null) { + getDataManager().updateUserPassword(user); + } + super.updateItem(user); + } + @Override protected void removeCachedItem(long userId) { User cachedUser = getById(userId); diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 2b850c755..e576a26b8 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -24,8 +24,8 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; +import org.traccar.storage.StorageException; -import java.sql.SQLException; import java.util.Date; @ChannelHandler.Sharable @@ -174,7 +174,7 @@ public class FilterHandler extends BaseDataHandler { try { Date newFixTime = position.getFixTime(); preceding = Context.getDataManager().getPrecedingPosition(deviceId, newFixTime); - } catch (SQLException e) { + } catch (StorageException e) { LOGGER.warn("Error retrieving preceding position; fallbacking to last received position.", e); preceding = getLastReceivedPosition(deviceId); } diff --git a/src/main/java/org/traccar/model/Attribute.java b/src/main/java/org/traccar/model/Attribute.java index 45d40b3ec..65f2e3881 100644 --- a/src/main/java/org/traccar/model/Attribute.java +++ b/src/main/java/org/traccar/model/Attribute.java @@ -16,6 +16,9 @@ */ package org.traccar.model; +import org.traccar.storage.StorageName; + +@StorageName("tc_attributes") public class Attribute extends BaseModel { private String description; diff --git a/src/main/java/org/traccar/model/Calendar.java b/src/main/java/org/traccar/model/Calendar.java index af6364626..102c0be52 100644 --- a/src/main/java/org/traccar/model/Calendar.java +++ b/src/main/java/org/traccar/model/Calendar.java @@ -25,6 +25,7 @@ import net.fortuna.ical4j.model.DateTime; import net.fortuna.ical4j.model.Period; import net.fortuna.ical4j.model.component.CalendarComponent; import org.traccar.storage.QueryIgnore; +import org.traccar.storage.StorageName; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -32,6 +33,7 @@ import java.time.Duration; import java.util.Collection; import java.util.Date; +@StorageName("tc_calendars") public class Calendar extends ExtendedModel { private String name; diff --git a/src/main/java/org/traccar/model/Command.java b/src/main/java/org/traccar/model/Command.java index 71bc232e9..03961c7b2 100644 --- a/src/main/java/org/traccar/model/Command.java +++ b/src/main/java/org/traccar/model/Command.java @@ -18,7 +18,9 @@ package org.traccar.model; import org.traccar.storage.QueryIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.traccar.storage.StorageName; +@StorageName("tc_commands") @JsonIgnoreProperties(ignoreUnknown = true) public class Command extends Message implements Cloneable { @@ -104,6 +106,12 @@ public class Command extends Message implements Cloneable { return super.getDeviceId(); } + @QueryIgnore + @Override + public void setDeviceId(long deviceId) { + super.setDeviceId(deviceId); + } + private String description; public String getDescription() { diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 46de8003d..836a6709c 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -20,7 +20,9 @@ import java.util.List; import org.traccar.storage.QueryExtended; import org.traccar.storage.QueryIgnore; +import org.traccar.storage.StorageName; +@StorageName("tc_devices") public class Device extends GroupedModel { private String name; @@ -54,13 +56,13 @@ public class Device extends GroupedModel { return status != null ? status : STATUS_OFFLINE; } + @QueryIgnore public void setStatus(String status) { this.status = status; } private Date lastUpdate; - @QueryExtended public Date getLastUpdate() { if (lastUpdate != null) { return new Date(lastUpdate.getTime()); @@ -69,6 +71,7 @@ public class Device extends GroupedModel { } } + @QueryExtended public void setLastUpdate(Date lastUpdate) { if (lastUpdate != null) { this.lastUpdate = new Date(lastUpdate.getTime()); @@ -84,6 +87,7 @@ public class Device extends GroupedModel { return positionId; } + @QueryIgnore public void setPositionId(long positionId) { this.positionId = positionId; } @@ -95,6 +99,7 @@ public class Device extends GroupedModel { return geofenceIds; } + @QueryIgnore public void setGeofenceIds(List geofenceIds) { this.geofenceIds = geofenceIds; } diff --git a/src/main/java/org/traccar/model/Driver.java b/src/main/java/org/traccar/model/Driver.java index 05f52fd4d..b9e023088 100644 --- a/src/main/java/org/traccar/model/Driver.java +++ b/src/main/java/org/traccar/model/Driver.java @@ -16,6 +16,9 @@ */ package org.traccar.model; +import org.traccar.storage.StorageName; + +@StorageName("tc_drivers") public class Driver extends ExtendedModel { private String name; @@ -37,4 +40,5 @@ public class Driver extends ExtendedModel { public void setUniqueId(String uniqueId) { this.uniqueId = uniqueId; } + } diff --git a/src/main/java/org/traccar/model/Event.java b/src/main/java/org/traccar/model/Event.java index a7a134ecf..6e3953fda 100644 --- a/src/main/java/org/traccar/model/Event.java +++ b/src/main/java/org/traccar/model/Event.java @@ -15,8 +15,11 @@ */ package org.traccar.model; +import org.traccar.storage.StorageName; + import java.util.Date; +@StorageName("tc_events") public class Event extends Message { public Event(String type, Position position) { diff --git a/src/main/java/org/traccar/model/Geofence.java b/src/main/java/org/traccar/model/Geofence.java index a451da9f5..5b857580d 100644 --- a/src/main/java/org/traccar/model/Geofence.java +++ b/src/main/java/org/traccar/model/Geofence.java @@ -26,7 +26,9 @@ import org.traccar.geofence.GeofencePolygon; import org.traccar.geofence.GeofencePolyline; import com.fasterxml.jackson.annotation.JsonIgnore; +import org.traccar.storage.StorageName; +@StorageName("tc_geofences") public class Geofence extends ScheduledModel { public static final String TYPE_GEOFENCE_CILCLE = "geofenceCircle"; diff --git a/src/main/java/org/traccar/model/Group.java b/src/main/java/org/traccar/model/Group.java index 91ea2319d..ff69f61fa 100644 --- a/src/main/java/org/traccar/model/Group.java +++ b/src/main/java/org/traccar/model/Group.java @@ -15,6 +15,9 @@ */ package org.traccar.model; +import org.traccar.storage.StorageName; + +@StorageName("tc_groups") public class Group extends GroupedModel { private String name; diff --git a/src/main/java/org/traccar/model/Maintenance.java b/src/main/java/org/traccar/model/Maintenance.java index 73f67ea96..cad100a3a 100644 --- a/src/main/java/org/traccar/model/Maintenance.java +++ b/src/main/java/org/traccar/model/Maintenance.java @@ -16,6 +16,9 @@ */ package org.traccar.model; +import org.traccar.storage.StorageName; + +@StorageName("tc_maintenances") public class Maintenance extends ExtendedModel { private String name; diff --git a/src/main/java/org/traccar/model/Notification.java b/src/main/java/org/traccar/model/Notification.java index 01ca2711c..95e446132 100644 --- a/src/main/java/org/traccar/model/Notification.java +++ b/src/main/java/org/traccar/model/Notification.java @@ -21,7 +21,9 @@ import java.util.Set; import org.traccar.storage.QueryIgnore; import com.fasterxml.jackson.annotation.JsonIgnore; +import org.traccar.storage.StorageName; +@StorageName("tc_notifications") public class Notification extends ScheduledModel { private boolean always; @@ -44,7 +46,6 @@ public class Notification extends ScheduledModel { this.type = type; } - private String notificators; public String getNotificators() { @@ -55,7 +56,6 @@ public class Notification extends ScheduledModel { this.notificators = transports; } - @JsonIgnore @QueryIgnore public Set getNotificatorsTypes() { diff --git a/src/main/java/org/traccar/model/Order.java b/src/main/java/org/traccar/model/Order.java index fe6d926b8..7d09b0a47 100644 --- a/src/main/java/org/traccar/model/Order.java +++ b/src/main/java/org/traccar/model/Order.java @@ -15,6 +15,9 @@ */ package org.traccar.model; +import org.traccar.storage.StorageName; + +@StorageName("tc_orders") public class Order extends ExtendedModel { private String uniqueId; diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index bbea58901..348370e2c 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -17,8 +17,11 @@ package org.traccar.model; import java.util.Date; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.traccar.storage.QueryIgnore; +import org.traccar.storage.StorageName; +@StorageName("tc_positions") public class Position extends Message { public static final String KEY_ORIGINAL = "raw"; @@ -190,6 +193,7 @@ public class Position extends Message { this.fixTime = fixTime; } + @QueryIgnore public void setTime(Date time) { setDeviceTime(time); setFixTime(time); @@ -202,6 +206,7 @@ public class Position extends Message { return outdated; } + @QueryIgnore public void setOutdated(boolean outdated) { this.outdated = outdated; } @@ -296,10 +301,18 @@ public class Position extends Message { this.network = network; } - @Override + @JsonIgnore @QueryIgnore + @Override public String getType() { return super.getType(); } + @JsonIgnore + @QueryIgnore + @Override + public void setType(String type) { + super.setType(type); + } + } diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index fdb071a18..b48e84939 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -18,7 +18,9 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.traccar.Context; import org.traccar.storage.QueryIgnore; +import org.traccar.storage.StorageName; +@StorageName("tc_servers") @JsonIgnoreProperties(ignoreUnknown = true) public class Server extends ExtendedModel { diff --git a/src/main/java/org/traccar/model/Statistics.java b/src/main/java/org/traccar/model/Statistics.java index a9a117aef..0dc1b98e8 100644 --- a/src/main/java/org/traccar/model/Statistics.java +++ b/src/main/java/org/traccar/model/Statistics.java @@ -15,9 +15,12 @@ */ package org.traccar.model; +import org.traccar.storage.StorageName; + import java.util.Date; import java.util.Map; +@StorageName("tc_statistics") public class Statistics extends ExtendedModel { private Date captureTime; diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 447cf691c..94828ab95 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -20,9 +20,11 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import org.traccar.storage.QueryExtended; import org.traccar.storage.QueryIgnore; import org.traccar.helper.Hashing; +import org.traccar.storage.StorageName; import java.util.Date; +@StorageName("tc_users") public class User extends ExtendedModel { private String name; diff --git a/src/main/java/org/traccar/reports/Events.java b/src/main/java/org/traccar/reports/Events.java index 66d9e708d..e4b905702 100644 --- a/src/main/java/org/traccar/reports/Events.java +++ b/src/main/java/org/traccar/reports/Events.java @@ -20,7 +20,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -35,6 +34,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.reports.model.DeviceReport; +import org.traccar.storage.StorageException; public final class Events { @@ -42,7 +42,7 @@ public final class Events { } public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Collection types, Date from, Date to) throws SQLException { + Collection types, Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { @@ -66,7 +66,7 @@ public final class Events { public static void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Collection types, Date from, Date to) throws SQLException, IOException { + Collection types, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); ArrayList devicesEvents = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); diff --git a/src/main/java/org/traccar/reports/Route.java b/src/main/java/org/traccar/reports/Route.java index 6adb00aae..4a5edd295 100644 --- a/src/main/java/org/traccar/reports/Route.java +++ b/src/main/java/org/traccar/reports/Route.java @@ -20,7 +20,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -31,6 +30,7 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.reports.model.DeviceReport; +import org.traccar.storage.StorageException; public final class Route { @@ -38,7 +38,7 @@ public final class Route { } public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws SQLException { + Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { @@ -50,7 +50,7 @@ public final class Route { public static void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws SQLException, IOException { + Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); diff --git a/src/main/java/org/traccar/reports/Stops.java b/src/main/java/org/traccar/reports/Stops.java index 2036b0641..36a4a7549 100644 --- a/src/main/java/org/traccar/reports/Stops.java +++ b/src/main/java/org/traccar/reports/Stops.java @@ -21,7 +21,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -35,13 +34,14 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.model.DeviceReport; import org.traccar.reports.model.StopReport; +import org.traccar.storage.StorageException; public final class Stops { private Stops() { } - private static Collection detectStops(long deviceId, Date from, Date to) throws SQLException { + private static Collection detectStops(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); @@ -55,7 +55,7 @@ public final class Stops { public static Collection getObjects( long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws SQLException { + Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { @@ -67,7 +67,7 @@ public final class Stops { public static void getExcel( OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws SQLException, IOException { + Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java index d576ac1e6..4924af062 100644 --- a/src/main/java/org/traccar/reports/Summary.java +++ b/src/main/java/org/traccar/reports/Summary.java @@ -20,7 +20,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; @@ -31,6 +30,7 @@ import org.traccar.Context; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import org.traccar.reports.model.SummaryReport; +import org.traccar.storage.StorageException; public final class Summary { @@ -97,7 +97,7 @@ public final class Summary { } private static Collection calculateSummaryResults( - long userId, long deviceId, Date from, Date to, boolean daily) throws SQLException { + long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { ArrayList positions = new ArrayList<>(Context.getDataManager().getPositions(deviceId, from, to)); @@ -122,7 +122,7 @@ public final class Summary { } public static Collection getObjects(long userId, Collection deviceIds, - Collection groupIds, Date from, Date to, boolean daily) throws SQLException { + Collection groupIds, Date from, Date to, boolean daily) throws StorageException { ReportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { @@ -134,7 +134,7 @@ public final class Summary { public static void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Date from, Date to, boolean daily) throws SQLException, IOException { + Date from, Date to, boolean daily) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); String templatePath = Context.getConfig().getString("report.templatesPath", diff --git a/src/main/java/org/traccar/reports/Trips.java b/src/main/java/org/traccar/reports/Trips.java index 7c0cd6921..1461b869e 100644 --- a/src/main/java/org/traccar/reports/Trips.java +++ b/src/main/java/org/traccar/reports/Trips.java @@ -20,7 +20,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -34,13 +33,14 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.model.DeviceReport; import org.traccar.reports.model.TripReport; +import org.traccar.storage.StorageException; public final class Trips { private Trips() { } - private static Collection detectTrips(long deviceId, Date from, Date to) throws SQLException { + private static Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); @@ -53,7 +53,7 @@ public final class Trips { } public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws SQLException { + Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { @@ -65,7 +65,7 @@ public final class Trips { public static void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws SQLException, IOException { + Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 0bcab7d20..2c893ebbc 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -2,6 +2,7 @@ package org.traccar.storage; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; @@ -24,7 +25,7 @@ public class DatabaseStorage extends Storage { @Override public List getObjects(Class clazz, Request request) throws StorageException { StringBuilder query = new StringBuilder("SELECT "); - query.append(formatColumns(request.getColumns(), clazz, c -> c)); + query.append(formatColumns(request.getColumns(), clazz, "get", c -> c)); query.append(" FROM ").append(getTableName(clazz)); query.append(formatCondition(request.getCondition())); query.append(formatOrder(request.getOrder())); @@ -44,9 +45,9 @@ public class DatabaseStorage extends Storage { StringBuilder query = new StringBuilder("INSERT INTO "); query.append(getTableName(entity.getClass())); query.append("("); - query.append(formatColumns(request.getColumns(), entity.getClass(), c -> c)); + query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c)); query.append(") VALUES ("); - query.append(formatColumns(request.getColumns(), entity.getClass(), c -> ':' + c)); + query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> ':' + c)); query.append(")"); try { QueryBuilder builder = QueryBuilder.create(dataSource, query.toString(), true); @@ -62,7 +63,7 @@ public class DatabaseStorage extends Storage { StringBuilder query = new StringBuilder("UPDATE "); query.append(getTableName(entity.getClass())); query.append(" SET "); - query.append(formatColumns(request.getColumns(), entity.getClass(), c -> c + " = :" + c)); + query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c + " = :" + c)); query.append(formatCondition(request.getCondition())); try { QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); @@ -101,31 +102,46 @@ public class DatabaseStorage extends Storage { } private Map getConditionVariables(Condition genericCondition) { - Map result = new HashMap<>(); - if (genericCondition instanceof Condition.Equals) { - Condition.Equals condition = (Condition.Equals) genericCondition; - result.put(condition.getVariable(), condition.getValue()); + Map results = new HashMap<>(); + if (genericCondition instanceof Condition.Compare) { + Condition.Compare condition = (Condition.Compare) genericCondition; + if (condition.getValue() != null) { + results.put(condition.getVariable(), condition.getValue()); + } } else if (genericCondition instanceof Condition.Between) { Condition.Between condition = (Condition.Between) genericCondition; - result.put(condition.getFromVariable(), condition.getFromValue()); - result.put(condition.getToVariable(), condition.getToValue()); + results.put(condition.getFromVariable(), condition.getFromValue()); + results.put(condition.getToVariable(), condition.getToValue()); + } else if (genericCondition instanceof Condition.Binary) { + Condition.Binary condition = (Condition.Binary) genericCondition; + results.putAll(getConditionVariables(condition.getFirst())); + results.putAll(getConditionVariables(condition.getSecond())); } - return result; + return results; } - private String formatColumns(Columns columns, Class clazz, Function mapper) { - return columns.getColumns(clazz).stream().map(mapper).collect(Collectors.joining(", ")); + private String formatColumns( + Columns columns, Class clazz, String type, Function mapper) { + return columns.getColumns(clazz, type).stream().map(mapper).collect(Collectors.joining(", ")); } private String formatCondition(Condition genericCondition) { + return formatCondition(genericCondition, true); + } + + private String formatCondition(Condition genericCondition, boolean appendWhere) { StringBuilder result = new StringBuilder(); if (genericCondition != null) { - result.append(" WHERE "); - if (genericCondition instanceof Condition.Equals) { + if (appendWhere) { + result.append(" WHERE "); + } + if (genericCondition instanceof Condition.Compare) { - Condition.Equals condition = (Condition.Equals) genericCondition; + Condition.Compare condition = (Condition.Compare) genericCondition; result.append(condition.getColumn()); - result.append(" == :"); + result.append(" "); + result.append(condition.getOperator()); + result.append(" :"); result.append(condition.getVariable()); } else if (genericCondition instanceof Condition.Between) { @@ -137,12 +153,14 @@ public class DatabaseStorage extends Storage { result.append(" AND :"); result.append(condition.getToVariable()); - } else if (genericCondition instanceof Condition.And) { + } else if (genericCondition instanceof Condition.Binary) { - Condition.And condition = (Condition.And) genericCondition; - result.append(formatCondition(condition.getFirst())); - result.append(" AND "); - result.append(formatCondition(condition.getSecond())); + Condition.Binary condition = (Condition.Binary) genericCondition; + result.append(formatCondition(condition.getFirst(), false)); + result.append(" "); + result.append(condition.getOperator()); + result.append(" "); + result.append(formatCondition(condition.getSecond(), false)); } } @@ -161,4 +179,13 @@ public class DatabaseStorage extends Storage { return result.toString(); } + private String formatLimit(Limit limit) { + StringBuilder result = new StringBuilder(); + if (limit != null) { + result.append(" LIMIT "); + result.append(limit.getValue()); + } + return result.toString(); + } + } diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index 838472c8b..edaacb74d 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -276,8 +276,7 @@ public final class QueryBuilder { Method[] methods = object.getClass().getMethods(); for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 - && !method.isAnnotationPresent(QueryIgnore.class)) { + if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { String name = method.getName().substring(3); try { if (method.getReturnType().equals(boolean.class)) { @@ -412,8 +411,7 @@ public final class QueryBuilder { Method[] methods = clazz.getMethods(); for (final Method method : methods) { - if (method.getName().startsWith("set") && method.getParameterTypes().length == 1 - && !method.isAnnotationPresent(QueryIgnore.class)) { + if (method.getName().startsWith("set") && method.getParameterTypes().length == 1) { final String name = method.getName().substring(3); diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java index b95ce9505..3726fbf50 100644 --- a/src/main/java/org/traccar/storage/Storage.java +++ b/src/main/java/org/traccar/storage/Storage.java @@ -6,20 +6,17 @@ import java.util.List; public abstract class Storage { - abstract List getObjects(Class clazz, Request request) throws StorageException; + public abstract List getObjects(Class clazz, Request request) throws StorageException; - abstract long addObject(T entity, Request request) throws StorageException; + public abstract long addObject(T entity, Request request) throws StorageException; - abstract void updateObject(T entity, Request request) throws StorageException; + public abstract void updateObject(T entity, Request request) throws StorageException; - abstract void removeObject(Class clazz, Request request) throws StorageException; + public abstract void removeObject(Class clazz, Request request) throws StorageException; - T getObject(Class clazz, Request request) throws StorageException { + public T getObject(Class clazz, Request request) throws StorageException { var objects = getObjects(clazz, request); - if (objects.isEmpty()) { - throw new StorageException("No objects found"); - } - return objects.get(0); + return objects.isEmpty() ? null : objects.get(0); } } diff --git a/src/main/java/org/traccar/storage/query/Columns.java b/src/main/java/org/traccar/storage/query/Columns.java index 1a13665ee..196d2281c 100644 --- a/src/main/java/org/traccar/storage/query/Columns.java +++ b/src/main/java/org/traccar/storage/query/Columns.java @@ -1,5 +1,6 @@ package org.traccar.storage.query; +import org.traccar.storage.QueryExtended; import org.traccar.storage.QueryIgnore; import java.lang.reflect.Method; @@ -11,14 +12,17 @@ import java.util.stream.Collectors; public abstract class Columns { - public abstract List getColumns(Class clazz); + public abstract List getColumns(Class clazz, String type); - protected List getAllColumns(Class clazz) { + protected List getAllColumns(Class clazz, String type) { List columns = new LinkedList<>(); Method[] methods = clazz.getMethods(); for (Method method : methods) { - if (method.getName().startsWith("set") && method.getParameterTypes().length == 1 - && !method.isAnnotationPresent(QueryIgnore.class)) { + int parameterCount = type.equals("set") ? 1 : 0; + if (method.getName().startsWith(type) && method.getParameterTypes().length == parameterCount + && !method.isAnnotationPresent(QueryIgnore.class) + && !method.isAnnotationPresent(QueryExtended.class) + && !method.getName().equals("getClass")) { columns.add(method.getName().substring(3).toLowerCase()); } } @@ -27,8 +31,8 @@ public abstract class Columns { public static class All extends Columns { @Override - public List getColumns(Class clazz) { - return getAllColumns(clazz); + public List getColumns(Class clazz, String type) { + return getAllColumns(clazz, type); } } @@ -40,7 +44,7 @@ public abstract class Columns { } @Override - public List getColumns(Class clazz) { + public List getColumns(Class clazz, String type) { return columns; } } @@ -53,8 +57,8 @@ public abstract class Columns { } @Override - public List getColumns(Class clazz) { - return getAllColumns(clazz).stream() + public List getColumns(Class clazz, String type) { + return getAllColumns(clazz, type).stream() .filter(column -> !columns.contains(column)) .collect(Collectors.toList()); } diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 50d520bc7..82c8e8479 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -2,13 +2,25 @@ package org.traccar.storage.query; public interface Condition { - class Equals implements Condition { + class Equals extends Compare { + public Equals(String column, String variable) { + this(column, variable, null); + } + + public Equals(String column, String variable, Object value) { + super(column, "=", variable, value); + } + } + + class Compare implements Condition { private final String column; + private final String operator; private final String variable; private final Object value; - public Equals(String column, String variable, Object value) { + public Compare(String column, String operator, String variable, Object value) { this.column = column; + this.operator = operator; this.variable = variable; this.value = value; } @@ -17,6 +29,10 @@ public interface Condition { return column; } + public String getOperator() { + return operator; + } + public String getVariable() { return variable; } @@ -62,13 +78,27 @@ public interface Condition { } } - class And implements Condition { + class Or extends Binary { + public Or(Condition first, Condition second) { + super(first, second, "OR"); + } + } + + class And extends Binary { + public And(Condition first, Condition second) { + super(first, second, "AND"); + } + } + + class Binary implements Condition { private final Condition first; private final Condition second; + private final String operator; - public And(Condition first, Condition second) { + public Binary(Condition first, Condition second, String operator) { this.first = first; this.second = second; + this.operator = operator; } public Condition getFirst() { @@ -78,6 +108,10 @@ public interface Condition { public Condition getSecond() { return second; } + + public String getOperator() { + return operator; + } } } diff --git a/src/main/java/org/traccar/storage/query/Limit.java b/src/main/java/org/traccar/storage/query/Limit.java new file mode 100644 index 000000000..4a20f0ce2 --- /dev/null +++ b/src/main/java/org/traccar/storage/query/Limit.java @@ -0,0 +1,15 @@ +package org.traccar.storage.query; + +public class Limit { + + private final int value; + + public Limit(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + +} diff --git a/src/main/java/org/traccar/storage/query/Request.java b/src/main/java/org/traccar/storage/query/Request.java index 8536cafd0..a98dd48f7 100644 --- a/src/main/java/org/traccar/storage/query/Request.java +++ b/src/main/java/org/traccar/storage/query/Request.java @@ -5,11 +5,29 @@ public class Request { private final Columns columns; private final Condition condition; private final Order order; + private final Limit limit; + + public Request(Columns columns) { + this(columns, null, null); + } + + public Request(Condition condition) { + this(null, condition, null); + } + + public Request(Columns columns, Condition condition) { + this(columns, condition, null); + } public Request(Columns columns, Condition condition, Order order) { + this(columns, condition, order, null); + } + + public Request(Columns columns, Condition condition, Order order, Limit limit) { this.columns = columns; this.condition = condition; this.order = order; + this.limit = limit; } public Columns getColumns() { @@ -24,4 +42,8 @@ public class Request { return order; } + public Limit getLimit() { + return limit; + } + } diff --git a/src/test/java/org/traccar/database/DataManagerTest.java b/src/test/java/org/traccar/database/DataManagerTest.java deleted file mode 100644 index 23043e96e..000000000 --- a/src/test/java/org/traccar/database/DataManagerTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.traccar.database; - -import org.junit.Test; -import org.traccar.model.Attribute; -import org.traccar.model.Device; -import org.traccar.model.Driver; -import org.traccar.model.Geofence; -import org.traccar.model.Group; -import org.traccar.model.ManagedUser; -import org.traccar.model.Position; -import org.traccar.model.User; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class DataManagerTest { - - @Test - public void constructObjectQuery() { - assertEquals("SELECT * FROM tc_users", - DataManager.constructObjectQuery(DataManager.ACTION_SELECT_ALL, User.class, false)); - assertEquals("DELETE FROM tc_groups WHERE id = :id", - DataManager.constructObjectQuery(DataManager.ACTION_DELETE, Group.class, false)); - assertEquals("SELECT * FROM tc_positions WHERE id = :id", - DataManager.constructObjectQuery(DataManager.ACTION_SELECT, Position.class, false)); - - String insertDevice = DataManager.constructObjectQuery(DataManager.ACTION_INSERT, Device.class, false); - assertFalse(insertDevice.contains("class")); - assertFalse(insertDevice.contains("id")); - assertFalse(insertDevice.contains("status")); - assertFalse(insertDevice.contains("geofenceIds")); - - String updateDeviceStatus = DataManager.constructObjectQuery("update", Device.class, true); - assertTrue(updateDeviceStatus.contains("lastUpdate")); - - String updateUser = DataManager.constructObjectQuery(DataManager.ACTION_UPDATE, User.class, false); - assertFalse(updateUser.contains("class")); - assertFalse(updateUser.contains("password")); - assertFalse(updateUser.contains("salt")); - - String updateUserPassword = DataManager.constructObjectQuery(DataManager.ACTION_UPDATE, User.class, true); - assertFalse(updateUserPassword.contains("name")); - assertTrue(updateUserPassword.contains("hashedPassword")); - assertTrue(updateUserPassword.contains("salt")); - - String insertPosition = DataManager.constructObjectQuery(DataManager.ACTION_INSERT, Position.class, false); - assertFalse(insertPosition.contains("type")); - assertFalse(insertPosition.contains("outdated")); - - } - - @Test - public void constructPermissionsQuery() { - assertEquals("SELECT userId, deviceId FROM tc_user_device", - DataManager.constructPermissionQuery(DataManager.ACTION_SELECT_ALL, User.class, Device.class)); - - assertEquals("SELECT userId, managedUserId FROM tc_user_user", - DataManager.constructPermissionQuery(DataManager.ACTION_SELECT_ALL, User.class, ManagedUser.class)); - - assertEquals("SELECT deviceId, driverId FROM tc_device_driver", - DataManager.constructPermissionQuery(DataManager.ACTION_SELECT_ALL, Device.class, Driver.class)); - - assertEquals("SELECT groupId, geofenceId FROM tc_group_geofence", - DataManager.constructPermissionQuery(DataManager.ACTION_SELECT_ALL, Group.class, Geofence.class)); - - assertEquals("INSERT INTO tc_user_device (userId, deviceId) VALUES (:userId, :deviceId)", - DataManager.constructPermissionQuery(DataManager.ACTION_INSERT, User.class, Device.class)); - - assertEquals("DELETE FROM tc_user_user WHERE userId = :userId AND managedUserId = :managedUserId", - DataManager.constructPermissionQuery(DataManager.ACTION_DELETE, User.class, ManagedUser.class)); - - assertEquals("INSERT INTO tc_device_geofence (deviceId, geofenceId) VALUES (:deviceId, :geofenceId)", - DataManager.constructPermissionQuery(DataManager.ACTION_INSERT, Device.class, Geofence.class)); - - assertEquals("DELETE FROM tc_group_attribute WHERE groupId = :groupId AND attributeId = :attributeId", - DataManager.constructPermissionQuery(DataManager.ACTION_DELETE, Group.class, Attribute.class)); - - } - -} -- cgit v1.2.3 From 7c6b8e8754c5bd687b50349eb1ff8d651577d6cb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 14 Feb 2022 19:44:49 -0800 Subject: Decode Hoopo speed value --- src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java index 65333ba6e..af51a99c6 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,6 +62,10 @@ public class HoopoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_EVENT, eventData.getString("eventType")); position.set(Position.KEY_BATTERY_LEVEL, eventData.getInt("batteryLevel")); + if (json.containsKey("movement")) { + position.setSpeed(json.getJsonObject("movement").getInt("Speed")); + } + return position; } -- cgit v1.2.3 From ec889246f2d052f1878027cbf8f2e24435f09586 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 14 Feb 2022 19:45:41 -0800 Subject: Add test case --- src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java index 35d0f1423..3ee0a5e01 100644 --- a/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class HoopoProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "{ \"deviceId\": \"BCCD0654\", \"assetName\": \"BCCD0654\", \"assetType\": \"???? ?????? - ??? 8\", \"eventData\": { \"latitude\": 31.97498, \"longitude\": 34.80802, \"locationName\": \"\", \"accuracyLevel\": \"High\", \"eventType\": \"Arrival\", \"batteryLevel\": 100, \"receiveTime\": \"2021-09-20T18:52:32Z\" }, \"eventTime\": \"2021-09-20T08:52:02Z\", \"serverReportTime\": \"0001-01-01T00:00:00Z\" }")); + verifyPosition(decoder, text( + "{\"deviceId\":\"BCCD2559\",\"assetName\":\"BCCD2559\",\"assetType\":\"Standard\",\"eventData\":{\"latitude\":32.04746,\"longitude\":34.75843,\"locationName\":\"\",\"accuracyLevel\":\"?????\",\"eventType\":\"InMotion\",\"batteryLevel\":100,\"receiveTime\":\"2022-01-20T08:02:44Z\"},\"address\":{\"line1\":\"????????????70\",\"city\":\"??????-???\",\"stateOrProvince\":\"\",\"postalCode\":\"\",\"countryCode\":\"IL\"},\"movement\":{\"Speed\":1},\"eventTime\":\"2022-01-20T05:55:27Z\",\"serverReportTime\":\"2022-01-20T08:02:48Z\"}")); + } } -- cgit v1.2.3 From 85b3d963d7fcb0f13491baafd9b0159280e1af51 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 14 Feb 2022 19:48:32 -0800 Subject: Use mobile id for ORBCOMM --- src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index aff722c46..bc28498cc 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -70,7 +70,7 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < messages.size(); i++) { JsonObject message = messages.getJsonObject(i); DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, true, message.getJsonNumber("ID").toString()); + channel, remoteAddress, true, message.getString("MobileID")); if (deviceSession != null) { Position position = new Position(getProtocolName()); -- cgit v1.2.3 From 17d8ffe18170c422ac2c6dccef8361e1ca684548 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 14 Feb 2022 21:30:25 -0800 Subject: Extract package scanning --- src/main/java/org/traccar/ServerManager.java | 48 ++----------- src/main/java/org/traccar/helper/ClassScanner.java | 80 ++++++++++++++++++++++ 2 files changed, 84 insertions(+), 44 deletions(-) create mode 100644 src/main/java/org/traccar/helper/ClassScanner.java diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 0db786bdb..2e2cf7cff 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -18,23 +18,16 @@ package org.traccar; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Keys; +import org.traccar.helper.ClassScanner; -import java.io.File; import java.io.IOException; import java.net.BindException; import java.net.ConnectException; -import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; public class ServerManager { @@ -43,38 +36,9 @@ public class ServerManager { private final List connectorList = new LinkedList<>(); private final Map protocolList = new ConcurrentHashMap<>(); - private void loadPackage(String packageName) throws IOException, URISyntaxException, ReflectiveOperationException { - - List names = new LinkedList<>(); - String packagePath = packageName.replace('.', '/'); - URL packageUrl = getClass().getClassLoader().getResource(packagePath); - - if (packageUrl.getProtocol().equals("jar")) { - String jarFileName = URLDecoder.decode(packageUrl.getFile(), StandardCharsets.UTF_8.name()); - try (JarFile jf = new JarFile(jarFileName.substring(5, jarFileName.indexOf("!")))) { - Enumeration jarEntries = jf.entries(); - while (jarEntries.hasMoreElements()) { - String entryName = jarEntries.nextElement().getName(); - if (entryName.startsWith(packagePath) && entryName.length() > packagePath.length() + 5) { - names.add(entryName.substring(packagePath.length() + 1, entryName.lastIndexOf('.'))); - } - } - } - } else { - File folder = new File(new URI(packageUrl.toString())); - File[] files = folder.listFiles(); - if (files != null) { - for (File actual: files) { - String entryName = actual.getName(); - names.add(entryName.substring(0, entryName.lastIndexOf('.'))); - } - } - } - - for (String name : names) { - Class protocolClass = Class.forName(packageName + '.' + name); - if (BaseProtocol.class.isAssignableFrom(protocolClass) && Context.getConfig().hasKey( - Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { + public ServerManager() throws IOException, URISyntaxException, ReflectiveOperationException { + for (Class protocolClass : ClassScanner.findSubclasses(BaseProtocol.class, "org.traccar.protocol")) { + if (Context.getConfig().hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { BaseProtocol protocol = (BaseProtocol) protocolClass.getDeclaredConstructor().newInstance(); connectorList.addAll(protocol.getConnectorList()); protocolList.put(protocol.getName(), protocol); @@ -82,10 +46,6 @@ public class ServerManager { } } - public ServerManager() throws IOException, URISyntaxException, ReflectiveOperationException { - loadPackage("org.traccar.protocol"); - } - public BaseProtocol getProtocol(String name) { return protocolList.get(name); } diff --git a/src/main/java/org/traccar/helper/ClassScanner.java b/src/main/java/org/traccar/helper/ClassScanner.java new file mode 100644 index 000000000..c928f6a12 --- /dev/null +++ b/src/main/java/org/traccar/helper/ClassScanner.java @@ -0,0 +1,80 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.Enumeration; +import java.util.LinkedList; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +public final class ClassScanner { + + private ClassScanner() { + } + + public static List> findSubclasses( + Class baseClass) throws IOException, URISyntaxException, ReflectiveOperationException { + return findSubclasses(baseClass, baseClass.getPackageName()); + } + + public static List> findSubclasses(Class baseClass, String packageName) + throws IOException, URISyntaxException, ReflectiveOperationException { + + List names = new LinkedList<>(); + String packagePath = packageName.replace('.', '/'); + URL packageUrl = baseClass.getClassLoader().getResource(packagePath); + + if (packageUrl.getProtocol().equals("jar")) { + String jarFileName = URLDecoder.decode(packageUrl.getFile(), StandardCharsets.UTF_8.name()); + try (JarFile jf = new JarFile(jarFileName.substring(5, jarFileName.indexOf("!")))) { + Enumeration jarEntries = jf.entries(); + while (jarEntries.hasMoreElements()) { + String entryName = jarEntries.nextElement().getName(); + if (entryName.startsWith(packagePath) && entryName.length() > packagePath.length() + 5) { + names.add(entryName.substring(packagePath.length() + 1, entryName.lastIndexOf('.'))); + } + } + } + } else { + File folder = new File(new URI(packageUrl.toString())); + File[] files = folder.listFiles(); + if (files != null) { + for (File actual: files) { + String entryName = actual.getName(); + names.add(entryName.substring(0, entryName.lastIndexOf('.'))); + } + } + } + + var classes = new LinkedList>(); + for (String name : names) { + var clazz = Class.forName(packageName + '.' + name); + if (baseClass.isAssignableFrom(clazz)) { + classes.add(clazz); + } + } + return classes; + } + +} -- cgit v1.2.3 From dd8dbbf6fca2c61726431a8552640f2c1499b4a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 15 Feb 2022 22:55:53 -0800 Subject: Migrate permissions queries --- src/main/java/org/traccar/config/Keys.java | 7 - .../java/org/traccar/database/DataManager.java | 141 +-------------------- src/main/java/org/traccar/model/Permission.java | 95 ++++++++++++-- .../java/org/traccar/storage/DatabaseStorage.java | 50 ++++++++ .../java/org/traccar/storage/MemoryStorage.java | 16 +++ .../java/org/traccar/storage/QueryBuilder.java | 2 +- src/main/java/org/traccar/storage/Storage.java | 8 ++ 7 files changed, 164 insertions(+), 155 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index cb3bd4de8..ccfe4bee7 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -342,13 +342,6 @@ public final class Keys { "database.changelog", Collections.singletonList(KeyType.GLOBAL)); - /** - * Automatically generate SQL database queries when possible. - */ - public static final ConfigKey DATABASE_GENERATE_QUERIES = new ConfigKey<>( - "database.generateQueries", - Collections.singletonList(KeyType.GLOBAL)); - /** * Database connection pool size. Default value is defined by the HikariCP library. */ diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 303b8e033..178cbbc57 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -24,30 +24,18 @@ import liquibase.database.DatabaseFactory; import liquibase.exception.LiquibaseException; import liquibase.resource.FileSystemResourceAccessor; import liquibase.resource.ResourceAccessor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.model.Attribute; import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; -import org.traccar.model.Command; import org.traccar.model.Device; -import org.traccar.model.Driver; import org.traccar.model.Event; -import org.traccar.model.Geofence; -import org.traccar.model.Group; -import org.traccar.model.Maintenance; -import org.traccar.model.ManagedUser; -import org.traccar.model.Notification; import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.Statistics; import org.traccar.model.User; import org.traccar.storage.DatabaseStorage; -import org.traccar.storage.QueryBuilder; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -57,11 +45,9 @@ import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; import javax.sql.DataSource; -import java.beans.Introspector; import java.io.File; import java.lang.reflect.Method; import java.net.URL; -import java.sql.SQLException; import java.util.Collection; import java.util.Date; import java.util.LinkedList; @@ -69,14 +55,6 @@ import java.util.List; public class DataManager { - private static final Logger LOGGER = LoggerFactory.getLogger(DataManager.class); - - public static final String ACTION_SELECT_ALL = "selectAll"; - public static final String ACTION_SELECT = "select"; - public static final String ACTION_INSERT = "insert"; - public static final String ACTION_UPDATE = "update"; - public static final String ACTION_DELETE = "delete"; - private final Config config; private DataSource dataSource; @@ -87,8 +65,6 @@ public class DataManager { private final Storage storage; - private boolean generateQueries; - private final boolean forceLdap; public DataManager(Config config) throws Exception { @@ -137,72 +113,9 @@ public class DataManager { hikariConfig.setMaximumPoolSize(maxPoolSize); } - generateQueries = config.getBoolean(Keys.DATABASE_GENERATE_QUERIES); - dataSource = new HikariDataSource(hikariConfig); } - public static String constructPermissionQuery(String action, Class owner, Class property) { - switch (action) { - case ACTION_SELECT_ALL: - return "SELECT " + makeNameId(owner) + ", " + makeNameId(property) + " FROM " - + getPermissionsTableName(owner, property); - case ACTION_INSERT: - return "INSERT INTO " + getPermissionsTableName(owner, property) - + " (" + makeNameId(owner) + ", " + makeNameId(property) + ") VALUES (:" - + makeNameId(owner) + ", :" + makeNameId(property) + ")"; - case ACTION_DELETE: - return "DELETE FROM " + getPermissionsTableName(owner, property) - + " WHERE " + makeNameId(owner) + " = :" + makeNameId(owner) - + " AND " + makeNameId(property) + " = :" + makeNameId(property); - default: - throw new IllegalArgumentException("Unknown action"); - } - } - - public String getQuery(String action, Class owner, Class property) { - String queryName; - switch (action) { - case ACTION_SELECT_ALL: - queryName = "database.select" + owner.getSimpleName() + property.getSimpleName() + "s"; - break; - case ACTION_INSERT: - queryName = "database.link" + owner.getSimpleName() + property.getSimpleName(); - break; - default: - queryName = "database.unlink" + owner.getSimpleName() + property.getSimpleName(); - break; - } - String query = config.getString(queryName); - if (query == null) { - if (generateQueries) { - query = constructPermissionQuery( - action, owner, property.equals(User.class) ? ManagedUser.class : property); - } else { - LOGGER.info("Query not provided: " + queryName); - } - } - return query; - } - - private static String getPermissionsTableName(Class owner, Class property) { - String propertyName = property.getSimpleName(); - if (propertyName.equals("ManagedUser")) { - propertyName = "User"; - } - return "tc_" + Introspector.decapitalize(owner.getSimpleName()) - + "_" + Introspector.decapitalize(propertyName); - } - - private static String getObjectsTableName(Class clazz) { - String result = "tc_" + Introspector.decapitalize(clazz.getSimpleName()); - // Add "s" ending if object name is not plural already - if (!result.endsWith("s")) { - result += "s"; - } - return result; - } - private void initDatabaseSchema() throws LiquibaseException { if (config.hasKey(Keys.DATABASE_CHANGELOG)) { @@ -318,61 +231,17 @@ public class DataManager { new Order("captureTime"))); } - public static Class getClassByName(String name) throws ClassNotFoundException { - switch (name.toLowerCase().replace("id", "")) { - case "device": - return Device.class; - case "group": - return Group.class; - case "user": - return User.class; - case "manageduser": - return ManagedUser.class; - case "geofence": - return Geofence.class; - case "driver": - return Driver.class; - case "attribute": - return Attribute.class; - case "calendar": - return Calendar.class; - case "command": - return Command.class; - case "maintenance": - return Maintenance.class; - case "notification": - return Notification.class; - case "order": - return org.traccar.model.Order.class; - default: - throw new ClassNotFoundException(); - } - } - - private static String makeNameId(Class clazz) { - String name = clazz.getSimpleName(); - return Introspector.decapitalize(name) + (!name.contains("Id") ? "Id" : ""); - } - public Collection getPermissions(Class owner, Class property) throws StorageException, ClassNotFoundException { - try { - return QueryBuilder.create(dataSource, getQuery(ACTION_SELECT_ALL, owner, property)) - .executePermissionsQuery(); - } catch (SQLException e) { - throw new StorageException(e); - } + return storage.getPermissions(owner, property); } public void linkObject(Class owner, long ownerId, Class property, long propertyId, boolean link) throws StorageException { - try { - QueryBuilder.create(dataSource, getQuery(link ? ACTION_INSERT : ACTION_DELETE, owner, property)) - .setLong(makeNameId(owner), ownerId) - .setLong(makeNameId(property), propertyId) - .executeUpdate(); - } catch (SQLException e) { - throw new StorageException(e); + if (link) { + storage.addPermission(new Permission(owner, ownerId, property, propertyId)); + } else { + storage.removePermission(new Permission(owner, ownerId, property, propertyId)); } } diff --git a/src/main/java/org/traccar/model/Permission.java b/src/main/java/org/traccar/model/Permission.java index 6475a4582..ad0176b39 100644 --- a/src/main/java/org/traccar/model/Permission.java +++ b/src/main/java/org/traccar/model/Permission.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,42 +16,115 @@ */ package org.traccar.model; -import java.util.Iterator; +import java.beans.Introspector; +import java.io.IOException; +import java.net.URISyntaxException; import java.util.LinkedHashMap; import java.util.Map; +import java.util.TreeMap; -import org.traccar.database.DataManager; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.traccar.helper.ClassScanner; +import org.traccar.storage.QueryIgnore; public class Permission { + private static final Map> CLASSES = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + + static { + try { + for (Class clazz : ClassScanner.findSubclasses(BaseModel.class)) { + CLASSES.put(clazz.getSimpleName(), clazz); + } + } catch (IOException | ReflectiveOperationException | URISyntaxException e) { + throw new RuntimeException(e); + } + } + + private final LinkedHashMap data; + private final Class ownerClass; private final long ownerId; private final Class propertyClass; private final long propertyId; - public Permission(LinkedHashMap permissionMap) throws ClassNotFoundException { - Iterator> iterator = permissionMap.entrySet().iterator(); - String owner = iterator.next().getKey(); - ownerClass = DataManager.getClassByName(owner); - String property = iterator.next().getKey(); - propertyClass = DataManager.getClassByName(property); - ownerId = permissionMap.get(owner); - propertyId = permissionMap.get(property); + public Permission(LinkedHashMap data) { + this.data = data; + var iterator = data.entrySet().iterator(); + var owner = iterator.next(); + ownerClass = CLASSES.get(owner.getKey().substring(0, owner.getKey().length() - 2)); + ownerId = owner.getValue(); + var property = iterator.next(); + propertyClass = CLASSES.get(property.getKey().substring(0, property.getKey().length() - 2)); + propertyId = property.getValue(); } + public Permission(Class ownerClass, long ownerId, Class propertyClass, long propertyId) { + this.ownerClass = ownerClass; + this.ownerId = ownerId; + this.propertyClass = propertyClass; + this.propertyId = propertyId; + data = new LinkedHashMap<>(); + data.put(getKey(ownerClass), ownerId); + data.put(getKey(propertyClass), propertyId); + } + + private static String getKey(Class clazz) { + return Introspector.decapitalize(clazz.getSimpleName()) + "Id"; + } + + public static String getStorageName(Class ownerClass, Class propertyClass) { + String ownerName = ownerClass.getSimpleName(); + String propertyName = propertyClass.getSimpleName(); + String managedPrefix = "Managed"; + if (propertyName.startsWith(managedPrefix)) { + propertyName = propertyName.substring(managedPrefix.length()); + } + return "tc_" + Introspector.decapitalize(ownerName) + "_" + Introspector.decapitalize(propertyName); + } + + @QueryIgnore + @JsonIgnore + public String getStorageName() { + return getStorageName(ownerClass, propertyClass); + } + + @QueryIgnore + @JsonAnyGetter + public Map get() { + return data; + } + + @QueryIgnore + @JsonAnySetter + public void set(String key, Long value) { + data.put(key, value); + } + + @QueryIgnore + @JsonIgnore public Class getOwnerClass() { return ownerClass; } + @QueryIgnore + @JsonIgnore public long getOwnerId() { return ownerId; } + @QueryIgnore + @JsonIgnore public Class getPropertyClass() { return propertyClass; } + @QueryIgnore + @JsonIgnore public long getPropertyId() { return propertyId; } + } diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 2c893ebbc..d73dc7b25 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -1,5 +1,6 @@ package org.traccar.storage; +import org.traccar.model.Permission; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Limit; @@ -29,6 +30,7 @@ public class DatabaseStorage extends Storage { query.append(" FROM ").append(getTableName(clazz)); query.append(formatCondition(request.getCondition())); query.append(formatOrder(request.getOrder())); + query.append(formatLimit(request.getLimit())); try { QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { @@ -93,6 +95,54 @@ public class DatabaseStorage extends Storage { } } + @Override + public List getPermissions(Class ownerClass, Class propertyClass) throws StorageException { + StringBuilder query = new StringBuilder("SELECT * FROM "); + query.append(Permission.getStorageName(ownerClass, propertyClass)); + try { + QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + return builder.executePermissionsQuery(); + } catch (SQLException e) { + throw new StorageException(e); + } + } + + @Override + public void addPermission(Permission permission) throws StorageException { + StringBuilder query = new StringBuilder("INSERT INTO "); + query.append(permission.getStorageName()); + query.append(" VALUES ("); + query.append(permission.get().keySet().stream().map(key -> ':' + key).collect(Collectors.joining(", "))); + query.append(")"); + try { + QueryBuilder builder = QueryBuilder.create(dataSource, query.toString(), true); + for (var entry : permission.get().entrySet()) { + builder.setLong(entry.getKey(), entry.getValue()); + } + builder.executeUpdate(); + } catch (SQLException e) { + throw new StorageException(e); + } + } + + @Override + public void removePermission(Permission permission) throws StorageException { + StringBuilder query = new StringBuilder("DELETE FROM "); + query.append(permission.getStorageName()); + query.append(" WHERE "); + query.append(permission + .get().keySet().stream().map(key -> key + " = :" + key).collect(Collectors.joining(" AND "))); + try { + QueryBuilder builder = QueryBuilder.create(dataSource, query.toString(), true); + for (var entry : permission.get().entrySet()) { + builder.setLong(entry.getKey(), entry.getValue()); + } + builder.executeUpdate(); + } catch (SQLException e) { + throw new StorageException(e); + } + } + private String getTableName(Class clazz) throws StorageException { StorageName storageName = clazz.getAnnotation(StorageName.class); if (storageName == null) { diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java index 0ebd3b87e..0a2e5a81f 100644 --- a/src/main/java/org/traccar/storage/MemoryStorage.java +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -1,5 +1,6 @@ package org.traccar.storage; +import org.traccar.model.Permission; import org.traccar.storage.query.Request; import java.util.List; @@ -24,4 +25,19 @@ public class MemoryStorage extends Storage { public void removeObject(Class clazz, Request request) throws StorageException { } + @Override + public List getPermissions(Class ownerClass, Class propertyClass) throws StorageException { + return null; + } + + @Override + public void addPermission(Permission permission) throws StorageException { + + } + + @Override + public void removePermission(Permission permission) throws StorageException { + + } + } diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index edaacb74d..da8002f0b 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -472,7 +472,7 @@ public final class QueryBuilder { return 0; } - public List executePermissionsQuery() throws SQLException, ClassNotFoundException { + public List executePermissionsQuery() throws SQLException { List result = new LinkedList<>(); if (query != null) { try { diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java index 3726fbf50..22c48cae0 100644 --- a/src/main/java/org/traccar/storage/Storage.java +++ b/src/main/java/org/traccar/storage/Storage.java @@ -1,5 +1,6 @@ package org.traccar.storage; +import org.traccar.model.Permission; import org.traccar.storage.query.Request; import java.util.List; @@ -14,6 +15,13 @@ public abstract class Storage { public abstract void removeObject(Class clazz, Request request) throws StorageException; + public abstract List getPermissions( + Class ownerClass, Class propertyClass) throws StorageException; + + public abstract void addPermission(Permission permission) throws StorageException; + + public abstract void removePermission(Permission permission) throws StorageException; + public T getObject(Class clazz, Request request) throws StorageException { var objects = getObjects(clazz, request); return objects.isEmpty() ? null : objects.get(0); -- cgit v1.2.3 From 2e769ee25bf7d134e4625cc5814661588adf7794 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 15 Feb 2022 23:17:31 -0800 Subject: Implement memory permissions --- src/main/java/org/traccar/model/Pair.java | 44 ++++++++++++++++++++++ .../java/org/traccar/storage/MemoryStorage.java | 36 +++++++++++++----- 2 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/traccar/model/Pair.java diff --git a/src/main/java/org/traccar/model/Pair.java b/src/main/java/org/traccar/model/Pair.java new file mode 100644 index 000000000..fa856db96 --- /dev/null +++ b/src/main/java/org/traccar/model/Pair.java @@ -0,0 +1,44 @@ +package org.traccar.model; + +import java.util.Objects; + +public class Pair { + + private final K first; + private final V second; + + public Pair(K first, V second) { + this.first = first; + this.second = second; + } + + public K getFirst() { + return first; + } + + public V getSecond() { + return second; + } + + @SuppressWarnings("rawtypes") + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Pair pair = (Pair) o; + + if (!Objects.equals(first, pair.first)) return false; + if (!Objects.equals(second, pair.second)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = first != null ? first.hashCode() : 0; + result = 31 * result + (second != null ? second.hashCode() : 0); + return result; + } + +} diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java index 0a2e5a81f..9cfe30a2b 100644 --- a/src/main/java/org/traccar/storage/MemoryStorage.java +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -1,43 +1,59 @@ package org.traccar.storage; +import org.traccar.model.Pair; import org.traccar.model.Permission; import org.traccar.storage.query.Request; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; public class MemoryStorage extends Storage { + private final Map, Class>, Set>> permissions = new HashMap<>(); + @Override - public List getObjects(Class clazz, Request request) throws StorageException { + public List getObjects(Class clazz, Request request) { return null; } @Override - public long addObject(T entity, Request request) throws StorageException { + public long addObject(T entity, Request request) { return 0; } @Override - public void updateObject(T entity, Request request) throws StorageException { + public void updateObject(T entity, Request request) { } @Override - public void removeObject(Class clazz, Request request) throws StorageException { + public void removeObject(Class clazz, Request request) { } - @Override - public List getPermissions(Class ownerClass, Class propertyClass) throws StorageException { - return null; + private Set> getPermissionsSet(Class ownerClass, Class propertyClass) { + return permissions.computeIfAbsent(new Pair<>(ownerClass, propertyClass), k -> new HashSet<>()); } @Override - public void addPermission(Permission permission) throws StorageException { - + public List getPermissions(Class ownerClass, Class propertyClass) { + return getPermissionsSet(ownerClass, propertyClass).stream() + .map(pair -> new Permission(ownerClass, pair.getFirst(), propertyClass, pair.getSecond())) + .collect(Collectors.toList()); } @Override - public void removePermission(Permission permission) throws StorageException { + public void addPermission(Permission permission) { + getPermissionsSet(permission.getOwnerClass(), permission.getPropertyClass()) + .add(new Pair<>(permission.getOwnerId(), permission.getPropertyId())); + } + @Override + public void removePermission(Permission permission) { + getPermissionsSet(permission.getOwnerClass(), permission.getPropertyClass()) + .remove(new Pair<>(permission.getOwnerId(), permission.getPropertyId())); } } -- cgit v1.2.3 From b85d10bcc7baa7b7efafa82933a5abaaa8db2c92 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 15 Feb 2022 23:29:36 -0800 Subject: Fix style issues --- src/main/java/org/traccar/model/Pair.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/traccar/model/Pair.java b/src/main/java/org/traccar/model/Pair.java index fa856db96..b679de57b 100644 --- a/src/main/java/org/traccar/model/Pair.java +++ b/src/main/java/org/traccar/model/Pair.java @@ -23,22 +23,21 @@ public class Pair { @SuppressWarnings("rawtypes") @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } Pair pair = (Pair) o; - if (!Objects.equals(first, pair.first)) return false; - if (!Objects.equals(second, pair.second)) return false; - - return true; + return Objects.equals(first, pair.first) && Objects.equals(second, pair.second); } @Override public int hashCode() { - int result = first != null ? first.hashCode() : 0; - result = 31 * result + (second != null ? second.hashCode() : 0); - return result; + return Objects.hash(first, second); } } -- cgit v1.2.3 From f250352ef9fd36f4448a336a9c7b4411345c6285 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 16 Feb 2022 22:31:02 -0800 Subject: Convert to lower case --- src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index bc28498cc..64663374d 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -84,7 +84,7 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { for (int j = 0; j < fields.size(); j++) { JsonObject field = fields.getJsonObject(j); String value = field.getString("Value"); - switch (field.getString("Name")) { + switch (field.getString("Name").toLowerCase()) { case "latitude": position.setLatitude(Integer.parseInt(value) / 60000.0); break; @@ -97,7 +97,6 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { case "heading": position.setCourse(Integer.parseInt(value) * 0.1); break; - default: break; } -- cgit v1.2.3 From e901e80d26544e86a9e3509532de92ceed0b87a8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 17 Feb 2022 22:51:53 -0800 Subject: Make variable private --- src/main/java/org/traccar/api/UserSecurityContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/api/UserSecurityContext.java b/src/main/java/org/traccar/api/UserSecurityContext.java index 55c0621bc..6773230fa 100644 --- a/src/main/java/org/traccar/api/UserSecurityContext.java +++ b/src/main/java/org/traccar/api/UserSecurityContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,7 +20,7 @@ import java.security.Principal; public class UserSecurityContext implements SecurityContext { - private UserPrincipal principal; + private final UserPrincipal principal; public UserSecurityContext(UserPrincipal principal) { this.principal = principal; -- cgit v1.2.3 From b5b9eb8207f42235f7ed2a52a6424f5629590992 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 18 Feb 2022 00:00:12 -0800 Subject: Migrate server API to storage --- build.gradle | 1 + src/main/java/org/traccar/MainModule.java | 6 ++++++ src/main/java/org/traccar/api/BaseResource.java | 3 ++- .../org/traccar/api/resource/ServerResource.java | 17 ++++++++------- .../java/org/traccar/database/DataManager.java | 4 ++++ src/main/java/org/traccar/web/WebServer.java | 24 ++++++++++++++++++++++ 6 files changed, 47 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index b75ad6ff4..d89b5a6a5 100644 --- a/build.gradle +++ b/build.gradle @@ -62,6 +62,7 @@ dependencies { implementation "org.glassfish.jersey.containers:jersey-container-servlet:$jerseyVersion" implementation "org.glassfish.jersey.media:jersey-media-json-jackson:$jerseyVersion" implementation "org.glassfish.jersey.inject:jersey-hk2:$jerseyVersion" + implementation "org.glassfish.hk2:guice-bridge:2.6.1" // same version as jersey-hk2 implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" implementation "org.liquibase:liquibase-core:4.7.0" diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index aaa82adfc..d72e04588 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -84,6 +84,7 @@ import javax.ws.rs.client.Client; import io.netty.util.Timer; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; +import org.traccar.storage.Storage; public class MainModule extends AbstractModule { @@ -97,6 +98,11 @@ public class MainModule extends AbstractModule { return Context.getConfig(); } + @Provides + public static Storage provideStorage() { + return Context.getDataManager().getStorage(); + } + @Provides public static DataManager provideDataManager() { return Context.getDataManager(); diff --git a/src/main/java/org/traccar/api/BaseResource.java b/src/main/java/org/traccar/api/BaseResource.java index cc272df9c..56bf70cf0 100644 --- a/src/main/java/org/traccar/api/BaseResource.java +++ b/src/main/java/org/traccar/api/BaseResource.java @@ -15,11 +15,12 @@ */ package org.traccar.api; +import javax.ws.rs.core.Context; import javax.ws.rs.core.SecurityContext; public class BaseResource { - @javax.ws.rs.core.Context + @Context private SecurityContext securityContext; protected long getUserId() { diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 8096c66fa..2d17d5e47 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,13 @@ import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Server; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.PUT; @@ -36,14 +40,13 @@ import javax.ws.rs.core.Response; @Consumes(MediaType.APPLICATION_JSON) public class ServerResource extends BaseResource { + @Inject + private Storage storage; + @PermitAll @GET - public Server get(@QueryParam("force") boolean force) throws StorageException { - if (force) { - return Context.getDataManager().getServer(); - } else { - return Context.getPermissionsManager().getServer(); - } + public Server get() throws StorageException { + return storage.getObject(Server.class, new Request(new Columns.All())); } @PUT diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 178cbbc57..9ac808a69 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -65,6 +65,10 @@ public class DataManager { private final Storage storage; + public Storage getStorage() { + return storage; + } + private final boolean forceLdap; public DataManager(Config config) throws Exception { diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 604edfedc..46c1f3912 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -35,12 +35,18 @@ import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; +import org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.spi.Container; +import org.glassfish.jersey.server.spi.ContainerLifecycleListener; import org.glassfish.jersey.servlet.ServletContainer; +import org.jvnet.hk2.guice.bridge.api.GuiceBridge; +import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; import org.traccar.api.DateParameterConverterProvider; import org.traccar.config.Config; import org.traccar.api.AsyncSocketServlet; @@ -174,6 +180,24 @@ public class WebServer { JacksonFeature.class, ObjectMapperProvider.class, ResourceErrorHandler.class, SecurityRequestFilter.class, CorsResponseFilter.class, DateParameterConverterProvider.class); resourceConfig.packages(ServerResource.class.getPackage().getName()); + resourceConfig.register(new ContainerLifecycleListener() { + @Override + public void onStartup(Container container) { + var injectionManager = container.getApplicationHandler().getInjectionManager(); + var serviceLocator = ((ImmediateHk2InjectionManager) injectionManager).getServiceLocator(); + GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator); + var guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class); + guiceBridge.bridgeGuiceInjector(Main.getInjector()); + } + + @Override + public void onReload(Container container) { + } + + @Override + public void onShutdown(Container container) { + } + }); servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } -- cgit v1.2.3 From 9336e9f77ac101a4b0b061e61dbd43bc9567ef9c Mon Sep 17 00:00:00 2001 From: Eyk Haneklaus Date: Sat, 19 Feb 2022 18:01:39 +0100 Subject: Added support for YP14 from "1903" protocol specification --- src/main/java/org/traccar/protocol/TrvProtocolDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java index 05312b820..c72ae9859 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java @@ -59,7 +59,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(d)") // acc .number("(dd)") // arm status .number("(dd)") // working mode - .number("(?:[0-2]{3})?,") + .number("(?:d{3,5})?,") // (ignored) .number("(d+),") // mcc .number("(d+),") // mnc .number("(d+),") // lac @@ -183,7 +183,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type.equals("AP01") || type.equals("AP10") || type.equals("YP03")) { + } else if (type.equals("AP01") || type.equals("AP10") || type.equals("YP03") || type.equals("YP14")) { Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java index 44735abcb..3cd283de7 100644 --- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -65,6 +65,7 @@ public class TrvProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "TRVAP10080524A2232.9806N11404.9355E000.1061830323.8706000908000502,460,0,9520,3671,00,zh-cn,00")); + verifyPosition(decoder, text( + "TRVYP14220217A5235.7885N00724.1840E000.0130919177.561000050660000200004,262,01,14635,52789,FritzBox7|DC-39-8F-7E-94-73|-89&FritzBox7|24-4E-5D-71-C3-9C|-90&MY_IOT|80-B4-F7-77-9C-7C|-81&MYAP|44-D4-F7-77-9C-7C|-80#")); } - } -- cgit v1.2.3 From 3314863a973321e9b1aecde30c09be3dc13a2ed8 Mon Sep 17 00:00:00 2001 From: 4alexbo <6820539+4alexbo@users.noreply.github.com> Date: Sun, 20 Feb 2022 14:24:35 +0100 Subject: removed comment from TrvProtocolDecoder --- src/main/java/org/traccar/protocol/TrvProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java index c72ae9859..e62cdf404 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java @@ -59,7 +59,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(d)") // acc .number("(dd)") // arm status .number("(dd)") // working mode - .number("(?:d{3,5})?,") // (ignored) + .number("(?:d{3,5})?,") .number("(d+),") // mcc .number("(d+),") // mnc .number("(d+),") // lac -- cgit v1.2.3 From dac1ae332fcde1ed3eb4e21be2606b8aac4cab26 Mon Sep 17 00:00:00 2001 From: 4alexbo <6820539+4alexbo@users.noreply.github.com> Date: Sun, 20 Feb 2022 14:30:38 +0100 Subject: re-added empty lines according to typical coding style --- src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java index 3cd283de7..e1eaef87b 100644 --- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -67,5 +67,7 @@ public class TrvProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "TRVYP14220217A5235.7885N00724.1840E000.0130919177.561000050660000200004,262,01,14635,52789,FritzBox7|DC-39-8F-7E-94-73|-89&FritzBox7|24-4E-5D-71-C3-9C|-90&MY_IOT|80-B4-F7-77-9C-7C|-81&MYAP|44-D4-F7-77-9C-7C|-80#")); + } + } -- cgit v1.2.3 From 0f9923dc1dda589848d26ac19bfccbaabe3ca8b6 Mon Sep 17 00:00:00 2001 From: 4alexbo <6820539+4alexbo@users.noreply.github.com> Date: Sun, 20 Feb 2022 20:58:37 +0100 Subject: Removed white spaces --- src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java index e1eaef87b..33d4e0124 100644 --- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -67,7 +67,7 @@ public class TrvProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "TRVYP14220217A5235.7885N00724.1840E000.0130919177.561000050660000200004,262,01,14635,52789,FritzBox7|DC-39-8F-7E-94-73|-89&FritzBox7|24-4E-5D-71-C3-9C|-90&MY_IOT|80-B4-F7-77-9C-7C|-81&MYAP|44-D4-F7-77-9C-7C|-80#")); - + } - + } -- cgit v1.2.3 From 4b4201de3519ce744dcbba303bd10aaaa4d3fa7b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 20 Feb 2022 23:10:45 -0800 Subject: Remove unnecessary file --- .../java/org/traccar/api/ObjectMapperProvider.java | 32 ---------------------- src/main/java/org/traccar/web/WebServer.java | 3 +- 2 files changed, 1 insertion(+), 34 deletions(-) delete mode 100644 src/main/java/org/traccar/api/ObjectMapperProvider.java diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java deleted file mode 100644 index f81b20917..000000000 --- a/src/main/java/org/traccar/api/ObjectMapperProvider.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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.api; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.traccar.Context; - -import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; - -@Provider -public class ObjectMapperProvider implements ContextResolver { - - @Override - public ObjectMapper getContext(Class type) { - return Context.getObjectMapper(); - } - -} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 46c1f3912..c8c564940 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -52,7 +52,6 @@ import org.traccar.config.Config; import org.traccar.api.AsyncSocketServlet; import org.traccar.api.CorsResponseFilter; import org.traccar.api.MediaFilter; -import org.traccar.api.ObjectMapperProvider; import org.traccar.api.ResourceErrorHandler; import org.traccar.api.SecurityRequestFilter; import org.traccar.api.resource.ServerResource; @@ -177,7 +176,7 @@ public class WebServer { ResourceConfig resourceConfig = new ResourceConfig(); resourceConfig.registerClasses( - JacksonFeature.class, ObjectMapperProvider.class, ResourceErrorHandler.class, + JacksonFeature.class, ResourceErrorHandler.class, SecurityRequestFilter.class, CorsResponseFilter.class, DateParameterConverterProvider.class); resourceConfig.packages(ServerResource.class.getPackage().getName()); resourceConfig.register(new ContainerLifecycleListener() { -- cgit v1.2.3 From 7d66054920a496399cb0e20f10556ae78c3ee009 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 20 Feb 2022 23:12:01 -0800 Subject: Add security package --- src/main/java/org/traccar/api/BaseResource.java | 2 + .../org/traccar/api/SecurityRequestFilter.java | 119 --------------------- src/main/java/org/traccar/api/UserPrincipal.java | 37 ------- .../java/org/traccar/api/UserSecurityContext.java | 49 --------- .../api/security/SecurityRequestFilter.java | 119 +++++++++++++++++++++ .../org/traccar/api/security/UserPrincipal.java | 37 +++++++ .../traccar/api/security/UserSecurityContext.java | 49 +++++++++ src/main/java/org/traccar/web/WebServer.java | 2 +- 8 files changed, 208 insertions(+), 206 deletions(-) delete mode 100644 src/main/java/org/traccar/api/SecurityRequestFilter.java delete mode 100644 src/main/java/org/traccar/api/UserPrincipal.java delete mode 100644 src/main/java/org/traccar/api/UserSecurityContext.java create mode 100644 src/main/java/org/traccar/api/security/SecurityRequestFilter.java create mode 100644 src/main/java/org/traccar/api/security/UserPrincipal.java create mode 100644 src/main/java/org/traccar/api/security/UserSecurityContext.java diff --git a/src/main/java/org/traccar/api/BaseResource.java b/src/main/java/org/traccar/api/BaseResource.java index 56bf70cf0..6dff8c8c3 100644 --- a/src/main/java/org/traccar/api/BaseResource.java +++ b/src/main/java/org/traccar/api/BaseResource.java @@ -15,6 +15,8 @@ */ package org.traccar.api; +import org.traccar.api.security.UserPrincipal; + import javax.ws.rs.core.Context; import javax.ws.rs.core.SecurityContext; diff --git a/src/main/java/org/traccar/api/SecurityRequestFilter.java b/src/main/java/org/traccar/api/SecurityRequestFilter.java deleted file mode 100644 index 6b190be9f..000000000 --- a/src/main/java/org/traccar/api/SecurityRequestFilter.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2015 - 2016 Anton Tananaev (anton@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.api; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.api.resource.SessionResource; -import org.traccar.database.StatisticsManager; -import org.traccar.helper.DataConverter; -import org.traccar.model.User; -import org.traccar.storage.StorageException; - -import javax.annotation.security.PermitAll; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerRequestFilter; -import javax.ws.rs.container.ResourceInfo; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.SecurityContext; -import java.lang.reflect.Method; -import java.nio.charset.StandardCharsets; - -public class SecurityRequestFilter implements ContainerRequestFilter { - - private static final Logger LOGGER = LoggerFactory.getLogger(SecurityRequestFilter.class); - - public static final String AUTHORIZATION_HEADER = "Authorization"; - public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; - public static final String BASIC_REALM = "Basic realm=\"api\""; - public static final String X_REQUESTED_WITH = "X-Requested-With"; - public static final String XML_HTTP_REQUEST = "XMLHttpRequest"; - - public static String[] decodeBasicAuth(String auth) { - auth = auth.replaceFirst("[B|b]asic ", ""); - byte[] decodedBytes = DataConverter.parseBase64(auth); - if (decodedBytes != null && decodedBytes.length > 0) { - return new String(decodedBytes, StandardCharsets.US_ASCII).split(":", 2); - } - return null; - } - - @javax.ws.rs.core.Context - private HttpServletRequest request; - - @javax.ws.rs.core.Context - private ResourceInfo resourceInfo; - - @Override - public void filter(ContainerRequestContext requestContext) { - - if (requestContext.getMethod().equals("OPTIONS")) { - return; - } - - SecurityContext securityContext = null; - - try { - - String authHeader = requestContext.getHeaderString(AUTHORIZATION_HEADER); - if (authHeader != null) { - - try { - String[] auth = decodeBasicAuth(authHeader); - User user = Context.getPermissionsManager().login(auth[0], auth[1]); - if (user != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(user.getId()); - securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); - } - } catch (StorageException e) { - throw new WebApplicationException(e); - } - - } else if (request.getSession() != null) { - - Long userId = (Long) request.getSession().getAttribute(SessionResource.USER_ID_KEY); - if (userId != null) { - Context.getPermissionsManager().checkUserEnabled(userId); - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); - securityContext = new UserSecurityContext(new UserPrincipal(userId)); - } - - } - - } catch (SecurityException e) { - LOGGER.warn("Authentication error", e); - } - - if (securityContext != null) { - requestContext.setSecurityContext(securityContext); - } else { - Method method = resourceInfo.getResourceMethod(); - if (!method.isAnnotationPresent(PermitAll.class)) { - Response.ResponseBuilder responseBuilder = Response.status(Response.Status.UNAUTHORIZED); - if (!XML_HTTP_REQUEST.equals(request.getHeader(X_REQUESTED_WITH))) { - responseBuilder.header(WWW_AUTHENTICATE, BASIC_REALM); - } - throw new WebApplicationException(responseBuilder.build()); - } - } - - } - -} diff --git a/src/main/java/org/traccar/api/UserPrincipal.java b/src/main/java/org/traccar/api/UserPrincipal.java deleted file mode 100644 index 175bca391..000000000 --- a/src/main/java/org/traccar/api/UserPrincipal.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2015 - 2020 Anton Tananaev (anton@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.api; - -import java.security.Principal; - -public class UserPrincipal implements Principal { - - private final long userId; - - public UserPrincipal(long userId) { - this.userId = userId; - } - - public Long getUserId() { - return userId; - } - - @Override - public String getName() { - return null; - } - -} diff --git a/src/main/java/org/traccar/api/UserSecurityContext.java b/src/main/java/org/traccar/api/UserSecurityContext.java deleted file mode 100644 index 6773230fa..000000000 --- a/src/main/java/org/traccar/api/UserSecurityContext.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2015 - 2022 Anton Tananaev (anton@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.api; - -import javax.ws.rs.core.SecurityContext; -import java.security.Principal; - -public class UserSecurityContext implements SecurityContext { - - private final UserPrincipal principal; - - public UserSecurityContext(UserPrincipal principal) { - this.principal = principal; - } - - @Override - public Principal getUserPrincipal() { - return principal; - } - - @Override - public boolean isUserInRole(String role) { - return true; - } - - @Override - public boolean isSecure() { - return false; - } - - @Override - public String getAuthenticationScheme() { - return BASIC_AUTH; - } - -} diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java new file mode 100644 index 000000000..9f20acb40 --- /dev/null +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -0,0 +1,119 @@ +/* + * Copyright 2015 - 2016 Anton Tananaev (anton@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.api.security; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.Context; +import org.traccar.Main; +import org.traccar.api.resource.SessionResource; +import org.traccar.database.StatisticsManager; +import org.traccar.helper.DataConverter; +import org.traccar.model.User; +import org.traccar.storage.StorageException; + +import javax.annotation.security.PermitAll; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.ResourceInfo; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; +import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; + +public class SecurityRequestFilter implements ContainerRequestFilter { + + private static final Logger LOGGER = LoggerFactory.getLogger(SecurityRequestFilter.class); + + public static final String AUTHORIZATION_HEADER = "Authorization"; + public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; + public static final String BASIC_REALM = "Basic realm=\"api\""; + public static final String X_REQUESTED_WITH = "X-Requested-With"; + public static final String XML_HTTP_REQUEST = "XMLHttpRequest"; + + public static String[] decodeBasicAuth(String auth) { + auth = auth.replaceFirst("[B|b]asic ", ""); + byte[] decodedBytes = DataConverter.parseBase64(auth); + if (decodedBytes != null && decodedBytes.length > 0) { + return new String(decodedBytes, StandardCharsets.US_ASCII).split(":", 2); + } + return null; + } + + @javax.ws.rs.core.Context + private HttpServletRequest request; + + @javax.ws.rs.core.Context + private ResourceInfo resourceInfo; + + @Override + public void filter(ContainerRequestContext requestContext) { + + if (requestContext.getMethod().equals("OPTIONS")) { + return; + } + + SecurityContext securityContext = null; + + try { + + String authHeader = requestContext.getHeaderString(AUTHORIZATION_HEADER); + if (authHeader != null) { + + try { + String[] auth = decodeBasicAuth(authHeader); + User user = Context.getPermissionsManager().login(auth[0], auth[1]); + if (user != null) { + Main.getInjector().getInstance(StatisticsManager.class).registerRequest(user.getId()); + securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); + } + } catch (StorageException e) { + throw new WebApplicationException(e); + } + + } else if (request.getSession() != null) { + + Long userId = (Long) request.getSession().getAttribute(SessionResource.USER_ID_KEY); + if (userId != null) { + Context.getPermissionsManager().checkUserEnabled(userId); + Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); + securityContext = new UserSecurityContext(new UserPrincipal(userId)); + } + + } + + } catch (SecurityException e) { + LOGGER.warn("Authentication error", e); + } + + if (securityContext != null) { + requestContext.setSecurityContext(securityContext); + } else { + Method method = resourceInfo.getResourceMethod(); + if (!method.isAnnotationPresent(PermitAll.class)) { + Response.ResponseBuilder responseBuilder = Response.status(Response.Status.UNAUTHORIZED); + if (!XML_HTTP_REQUEST.equals(request.getHeader(X_REQUESTED_WITH))) { + responseBuilder.header(WWW_AUTHENTICATE, BASIC_REALM); + } + throw new WebApplicationException(responseBuilder.build()); + } + } + + } + +} diff --git a/src/main/java/org/traccar/api/security/UserPrincipal.java b/src/main/java/org/traccar/api/security/UserPrincipal.java new file mode 100644 index 000000000..18b84a0e1 --- /dev/null +++ b/src/main/java/org/traccar/api/security/UserPrincipal.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015 - 2020 Anton Tananaev (anton@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.api.security; + +import java.security.Principal; + +public class UserPrincipal implements Principal { + + private final long userId; + + public UserPrincipal(long userId) { + this.userId = userId; + } + + public Long getUserId() { + return userId; + } + + @Override + public String getName() { + return null; + } + +} diff --git a/src/main/java/org/traccar/api/security/UserSecurityContext.java b/src/main/java/org/traccar/api/security/UserSecurityContext.java new file mode 100644 index 000000000..97df6b6c7 --- /dev/null +++ b/src/main/java/org/traccar/api/security/UserSecurityContext.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 - 2022 Anton Tananaev (anton@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.api.security; + +import javax.ws.rs.core.SecurityContext; +import java.security.Principal; + +public class UserSecurityContext implements SecurityContext { + + private final UserPrincipal principal; + + public UserSecurityContext(UserPrincipal principal) { + this.principal = principal; + } + + @Override + public Principal getUserPrincipal() { + return principal; + } + + @Override + public boolean isUserInRole(String role) { + return true; + } + + @Override + public boolean isSecure() { + return false; + } + + @Override + public String getAuthenticationScheme() { + return BASIC_AUTH; + } + +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index c8c564940..0364972d7 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -53,7 +53,7 @@ import org.traccar.api.AsyncSocketServlet; import org.traccar.api.CorsResponseFilter; import org.traccar.api.MediaFilter; import org.traccar.api.ResourceErrorHandler; -import org.traccar.api.SecurityRequestFilter; +import org.traccar.api.security.SecurityRequestFilter; import org.traccar.api.resource.ServerResource; import org.traccar.config.Keys; -- cgit v1.2.3 From 23bbb48eaf69db1c858a7f027d9f7a2fba8796ea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Feb 2022 11:22:07 -0800 Subject: Fix user creation --- src/main/java/org/traccar/model/User.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 94828ab95..792f2b669 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -249,6 +249,7 @@ public class User extends ExtendedModel { return null; } + @QueryIgnore public void setPassword(String password) { if (password != null && !password.isEmpty()) { Hashing.HashingResult hashingResult = Hashing.createHash(password); -- cgit v1.2.3 From 0afdd2dfc4f41bae865add997b5786220f1af1e3 Mon Sep 17 00:00:00 2001 From: Eyk Haneklaus Date: Sat, 19 Feb 2022 18:01:39 +0100 Subject: Added support for YP14 from "1903" protocol specification --- src/main/java/org/traccar/protocol/TrvProtocolDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java index 05312b820..c72ae9859 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java @@ -59,7 +59,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(d)") // acc .number("(dd)") // arm status .number("(dd)") // working mode - .number("(?:[0-2]{3})?,") + .number("(?:d{3,5})?,") // (ignored) .number("(d+),") // mcc .number("(d+),") // mnc .number("(d+),") // lac @@ -183,7 +183,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type.equals("AP01") || type.equals("AP10") || type.equals("YP03")) { + } else if (type.equals("AP01") || type.equals("AP10") || type.equals("YP03") || type.equals("YP14")) { Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java index 44735abcb..3cd283de7 100644 --- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -65,6 +65,7 @@ public class TrvProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "TRVAP10080524A2232.9806N11404.9355E000.1061830323.8706000908000502,460,0,9520,3671,00,zh-cn,00")); + verifyPosition(decoder, text( + "TRVYP14220217A5235.7885N00724.1840E000.0130919177.561000050660000200004,262,01,14635,52789,FritzBox7|DC-39-8F-7E-94-73|-89&FritzBox7|24-4E-5D-71-C3-9C|-90&MY_IOT|80-B4-F7-77-9C-7C|-81&MYAP|44-D4-F7-77-9C-7C|-80#")); } - } -- cgit v1.2.3 From 86768497bd8fbfbfe7b949fd3a28a5864d0d5964 Mon Sep 17 00:00:00 2001 From: 4alexbo <6820539+4alexbo@users.noreply.github.com> Date: Sun, 20 Feb 2022 14:24:35 +0100 Subject: removed comment from TrvProtocolDecoder --- src/main/java/org/traccar/protocol/TrvProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java index c72ae9859..e62cdf404 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java @@ -59,7 +59,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(d)") // acc .number("(dd)") // arm status .number("(dd)") // working mode - .number("(?:d{3,5})?,") // (ignored) + .number("(?:d{3,5})?,") .number("(d+),") // mcc .number("(d+),") // mnc .number("(d+),") // lac -- cgit v1.2.3 From bb3bcee67cd9c1072c1504cae1d4fbde5b0ec9fc Mon Sep 17 00:00:00 2001 From: 4alexbo <6820539+4alexbo@users.noreply.github.com> Date: Sun, 20 Feb 2022 14:30:38 +0100 Subject: re-added empty lines according to typical coding style --- src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java index 3cd283de7..e1eaef87b 100644 --- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -67,5 +67,7 @@ public class TrvProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "TRVYP14220217A5235.7885N00724.1840E000.0130919177.561000050660000200004,262,01,14635,52789,FritzBox7|DC-39-8F-7E-94-73|-89&FritzBox7|24-4E-5D-71-C3-9C|-90&MY_IOT|80-B4-F7-77-9C-7C|-81&MYAP|44-D4-F7-77-9C-7C|-80#")); + } + } -- cgit v1.2.3 From 7758221ed338ad145fc1861bf596546c34f74bc2 Mon Sep 17 00:00:00 2001 From: 4alexbo <6820539+4alexbo@users.noreply.github.com> Date: Sun, 20 Feb 2022 20:58:37 +0100 Subject: Removed white spaces --- src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java index e1eaef87b..33d4e0124 100644 --- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -67,7 +67,7 @@ public class TrvProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "TRVYP14220217A5235.7885N00724.1840E000.0130919177.561000050660000200004,262,01,14635,52789,FritzBox7|DC-39-8F-7E-94-73|-89&FritzBox7|24-4E-5D-71-C3-9C|-90&MY_IOT|80-B4-F7-77-9C-7C|-81&MYAP|44-D4-F7-77-9C-7C|-80#")); - + } - + } -- cgit v1.2.3 From 91c465faf6480d7aaf65073e70a42e4173d70eae Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Feb 2022 11:22:07 -0800 Subject: Fix user creation --- src/main/java/org/traccar/model/User.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 94828ab95..792f2b669 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -249,6 +249,7 @@ public class User extends ExtendedModel { return null; } + @QueryIgnore public void setPassword(String password) { if (password != null && !password.isEmpty()) { Hashing.HashingResult hashingResult = Hashing.createHash(password); -- cgit v1.2.3 From 73df090369b377dc55d77c6ada92722975d8fe99 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Feb 2022 23:01:02 -0800 Subject: Fix heading decoding --- src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java | 3 ++- src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index 64663374d..e7ea87428 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -95,7 +95,8 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(value))); break; case "heading": - position.setCourse(Integer.parseInt(value) * 0.1); + int heading = Integer.parseInt(value); + position.setCourse(heading <= 360 ? heading : 0); break; default: break; diff --git a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java index af35505d5..7d3068c02 100644 --- a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java @@ -14,7 +14,7 @@ public class OrbcommProtocolDecoderTest extends ProtocolTest { buffer("{\"ErrorID\":0,\"NextStartUTC\":\"\",\"Messages\":null}"))); verifyPositions(decoder, response( - buffer("{\"ErrorID\":0,\"NextStartUTC\":\"2022-01-20 21:17:19\",\"Messages\":[{\"ID\":21545955455454,\"MessageUTC\":\"2022-01-20 21:17:19\",\"ReceiveUTC\":\"2022-01-20 21:17:19\",\"SIN\":19,\"MobileID\":\"01097623SKY2C68\",\"Payload\":{\"Name\":\"simpleReport\",\"SIN\":19,\"MIN\":1,\"Fields\":[{\"Name\":\"latitude\",\"Value\":\"2717900\",\"Type\":\"signedint\"},{\"Name\":\"longitude\",\"Value\":\"-4555211\",\"Type\":\"signedint\"},{\"Name\":\"speed\",\"Value\":\"0\",\"Type\":\"unsignedint\"},{\"Name\":\"heading\",\"Value\":\"1439\",\"Type\":\"unsignedint\"}]},\"RegionName\":\"\",\"OTAMessageSize\":17,\"CustomerID\":0,\"Transport\":1,\"MobileOwnerID\":60000934}]}"))); + buffer("{\"ErrorID\":0,\"NextStartUTC\":\"2022-02-17 08:44:45\",\"Messages\":[{\"ID\":10343663424,\"MessageUTC\":\"2022-02-17 08:44:45\",\"ReceiveUTC\":\"2022-02-17 08:44:45\",\"SIN\":126,\"MobileID\":\"01452955SKYB444\",\"Payload\":{\"Name\":\"MovingIntervalSat\",\"SIN\":126,\"MIN\":22,\"Fields\":[{\"Name\":\"Latitude\",\"Value\":\"727668\"},{\"Name\":\"Longitude\",\"Value\":\"902276\"},{\"Name\":\"Speed\",\"Value\":\"0\"},{\"Name\":\"Heading\",\"Value\":\"361\"},{\"Name\":\"EventTime\",\"Value\":\"1645087473\"}]},\"RegionName\":\"EMEARB6\",\"OTAMessageSize\":16,\"CustomerID\":0,\"Transport\":1,\"MobileOwnerID\":60003097}]}"))); verifyPositions(decoder, false, response( buffer("{\"ErrorID\":0,\"NextStartUTC\":\"2016-10-13 15:19:59\",\"Messages\":[{\"ID\":120213064,\"MessageUTC\":\"2016-10-12 12:42:01\",\"ReceiveUTC\":\"2016-10-12 12:42:01\",\"SIN\":0,\"MobileID\":\"01173096SKY0E45\",\"Payload\":{\"Name\":\"modemRegistration\",\"SIN\":0,\"MIN\":0,\"Fields\":[{\"Name\":\"hardwareMajorVersion\",\"Value\":\"4\"},{\"Name\":\"hardwareMinorVersion\",\"Value\":\"2\"},{\"Name\":\"softwareMajorVersion\",\"Value\":\"13\"},{\"Name\":\"softwareMinorVersion\",\"Value\":\"1\"},{\"Name\":\"product\",\"Value\":\"4\"},{\"Name\":\"wakeupPeriod\",\"Value\":\"None\"},{\"Name\":\"lastResetReason\",\"Value\":\"Software\"},{\"Name\":\"virtualCarrier\",\"Value\":\"6\"},{\"Name\":\"beam\",\"Value\":\"1\"},{\"Name\":\"vain\",\"Value\":\"0\"},{\"Name\":\"reserved\",\"Value\":\"0\"},{\"Name\":\"operatorTxState\",\"Value\":\"0\"},{\"Name\":\"userTxState\",\"Value\":\"0\"},{\"Name\":\"broadcastIDCount\",\"Value\":\"0\"}],\"RegionName\":\"AMERRB11\",\"OTAMessageSize\":15,\"CustomerID\":0}}]}"))); -- cgit v1.2.3 From 82305faa20e383ea569bc5be17eb8cd74c6131f1 Mon Sep 17 00:00:00 2001 From: grmt Date: Tue, 22 Feb 2022 00:42:06 +0100 Subject: double rename for [to|from]Address into [to|from]address --- schema/changelog-4.16.xml | 6 ++++++ schema/changelog-master.xml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/schema/changelog-4.16.xml b/schema/changelog-4.16.xml index 0b6493f03..adf8d4fc6 100644 --- a/schema/changelog-4.16.xml +++ b/schema/changelog-4.16.xml @@ -16,6 +16,12 @@ + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index 354037cdd..d79e084f6 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -1,4 +1,4 @@ - + Date: Tue, 22 Feb 2022 19:42:25 -0800 Subject: Fix C2STek MT-20N decoding --- src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java | 8 +++++--- src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java | 5 ++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java index 83e62ff86..e735c67a1 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,7 +50,7 @@ public class C2stekProtocolDecoder extends BaseProtocolDecoder { .number("(d+)#") // battery .number("d+#") // geo area alarm .number("(x+)#") // alarm - .number("([01])") // armed + .number("([01])?") // armed .number("([01])") // door .number("([01])#") // ignition .any() @@ -111,7 +111,9 @@ public class C2stekProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextInt() * 0.001); position.set(Position.KEY_ALARM, decodeAlarm(parser.nextHexInt())); - position.set(Position.KEY_ARMED, parser.nextInt() > 0); + if (parser.hasNext()) { + position.set(Position.KEY_ARMED, parser.nextInt() > 0); + } position.set(Position.KEY_DOOR, parser.nextInt() > 0); position.set(Position.KEY_IGNITION, parser.nextInt() > 0); diff --git a/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java index d6831c1cf..6fb14b902 100644 --- a/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java @@ -10,7 +10,10 @@ public class C2stekProtocolDecoderTest extends ProtocolTest { var decoder = new C2stekProtocolDecoder(null); - verifyNull(decoder, text( + verifyPosition(decoder, text( + "PA$867965024889327$D#220222#135059#0#+37.98995#+23.85141#0.00#69.2#0.0#0000#000#8#00#sz-w1001#B2600$AP")); + + verifyPosition(decoder, text( "PA$863083038046613$D#181123#162850#1#+37.92684#+23.75933#0.62#200.1#0.0#3768#000#9#00#sz-w1001#B0907839$AP")); verifyPosition(decoder, text( -- cgit v1.2.3 From 35cfbcf182e3ccb6497e15febb0b12284e4c3c04 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 24 Feb 2022 22:28:02 -0800 Subject: Fix user update --- src/main/java/org/traccar/model/User.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 792f2b669..464d0cbfe 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -266,6 +266,7 @@ public class User extends ExtendedModel { return hashedPassword; } + @QueryExtended public void setHashedPassword(String hashedPassword) { this.hashedPassword = hashedPassword; } @@ -278,6 +279,7 @@ public class User extends ExtendedModel { return salt; } + @QueryExtended public void setSalt(String salt) { this.salt = salt; } -- cgit v1.2.3 From 90e50e3aafbbcdf3f2ac5698302b939c7149c578 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 1 Mar 2022 22:22:04 -0800 Subject: Fix Navtelecom checksum --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 8314442a3..7b3b5774c 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -239,7 +239,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { ByteBuf response = Unpooled.buffer(); response.writeCharSequence(type, StandardCharsets.US_ASCII); response.writeByte(count); - response.writeByte(Checksum.xor(response.nioBuffer())); + response.writeByte(Checksum.crc8(Checksum.CRC8_ROHC, response.nioBuffer())); channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } -- cgit v1.2.3 From a28e97150614a23e8a492e9379a579aa7240a0cd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 1 Mar 2022 22:48:56 -0800 Subject: Additional FlexAPI attributes --- .../traccar/protocol/FlexApiProtocolDecoder.java | 24 ++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index 20ff78c21..bcfbdd7da 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -68,11 +68,13 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(payload.getJsonNumber("gnss.longitude").doubleValue()); } + position.setValid(payload.getInt("gnss.fix") > 0); position.setAltitude(payload.getJsonNumber("gnss.altitude").doubleValue()); position.setSpeed(payload.getJsonNumber("gnss.speed").doubleValue()); position.setCourse(payload.getJsonNumber("gnss.heading").doubleValue()); position.set(Position.KEY_SATELLITES, payload.getInt("gnss.num_sv")); + position.set(Position.KEY_HDOP, payload.getJsonNumber("gnss.hdop").doubleValue()); } else if (topic.contains("/cellular1/")) { @@ -84,12 +86,26 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { String operator = payload.getString("modem1.operator"); if (!operator.isEmpty()) { - position.setNetwork(new Network(CellTower.from( + CellTower cellTower = CellTower.from( Integer.parseInt(operator.substring(0, 3)), Integer.parseInt(operator.substring(3)), Integer.parseInt(payload.getString("modem1.lac"), 16), Integer.parseInt(payload.getString("modem1.cell_id"), 16), - payload.getInt("modem1.rssi")))); + payload.getInt("modem1.rssi")); + switch (payload.getInt("modem1.network")) { + case 1: + cellTower.setRadioType("gsm"); + break; + case 2: + cellTower.setRadioType("wcdma"); + break; + case 3: + cellTower.setRadioType("lte"); + break; + default: + break; + } + position.setNetwork(new Network(cellTower)); } } else if (topic.contains("/obd/")) { @@ -124,8 +140,8 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, new Date(payload.getInt("io.ts") * 1000L)); - if (payload.containsKey("io.IGN")) { - position.set(Position.KEY_IGNITION, payload.getInt("io.IGN") > 0); + if (payload.containsKey("io.IGT")) { + position.set(Position.KEY_IGNITION, payload.getInt("io.IGT") > 0); } for (String key : payload.keySet()) { -- cgit v1.2.3 From 8561b2480c2a0c7d87a5dbbb789e180b4c61fb0a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 2 Mar 2022 21:02:06 -0800 Subject: Decode GL200 validity flag --- src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java | 1 + src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 7ce0c425d..280986165 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -377,6 +377,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(?:[0-9A-Z]{2}xxxx)?,").optional() // protocol version .number("(d{15}|x{14}),") // imei .any() + .text(",") .number("(d{1,2})?,") // hdop .number("(d{1,3}.d)?,") // speed .number("(d{1,3})?,") // course diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 9fab7e010..429ee15c7 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = new Gl200TextProtocolDecoder(null); + verifyPosition(decoder, buffer( + "+RESP:GTFRI,5E0100,861971050039361,,,,10,1,1,10.4,140,196.9,-80.709946,35.016525,20220302220944,0310,0260,1CE9,52A1,00,0.0,,,,,420000,,,,20220302220948,1B0B$")); + verifyAttribute(decoder, buffer( "+RESP:GTFRI,423031,866873025895726,,0,1,1,0,1,16,0.0,351,51.6,121.391063,31.164633,20181212072535,460,00,1877,DAE,00,3,85,20181212072535,002C$"), Position.KEY_BATTERY_LEVEL, 85); -- cgit v1.2.3 From fdf49e82c6ac0a3166d65797f3c773df70ff4494 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Mar 2022 21:03:33 -0800 Subject: Fix Navtelecom checksum --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 7b3b5774c..5d3a81f2a 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -239,7 +239,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { ByteBuf response = Unpooled.buffer(); response.writeCharSequence(type, StandardCharsets.US_ASCII); response.writeByte(count); - response.writeByte(Checksum.crc8(Checksum.CRC8_ROHC, response.nioBuffer())); + response.writeByte(Checksum.crc8(Checksum.CRC8_EGTS, response.nioBuffer())); channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } -- cgit v1.2.3 From 10c878dac30e671e7b0c2a08163ef4aa893910b8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Mar 2022 21:19:13 -0800 Subject: Use default proto directory --- .gitignore | 1 - build.gradle | 1 - 2 files changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index f2672aada..c005ef9e4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,3 @@ nbactions.xml .gradle out build -src/main/java/org/traccar/protobuf diff --git a/build.gradle b/build.gradle index d89b5a6a5..0b3f54355 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,6 @@ checkstyle { } protobuf { - generatedFilesBaseDir = "$projectDir/src" protoc { artifact = "com.google.protobuf:protoc:$protobufVersion" } -- cgit v1.2.3 From 76873ef0a00b0b5f71755e754b134c9cb34efc6e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Mar 2022 23:01:46 -0800 Subject: Add SKY IoT TeraTrack protocol --- setup/default.xml | 1 + .../org/traccar/protocol/TeraTrackProtocol.java | 39 +++++++++++ .../traccar/protocol/TeraTrackProtocolDecoder.java | 80 ++++++++++++++++++++++ .../protocol/TeraTrackProtocolDecoderTest.java | 19 +++++ 4 files changed, 139 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/TeraTrackProtocol.java create mode 100644 src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index a1ba5ca33..306421675 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -282,5 +282,6 @@ 5236 5237 5238 + 5239 diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java new file mode 100644 index 000000000..87d84be44 --- /dev/null +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.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 TeraTrackProtocol extends BaseProtocol { + + public TeraTrackProtocol() { + addServer(new TrackerServer(false, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new HttpResponseEncoder()); + pipeline.addLast(new HttpRequestDecoder()); + pipeline.addLast(new HttpObjectAggregator(65535)); + pipeline.addLast(new TeraTrackProtocolDecoder(TeraTrackProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java new file mode 100644 index 000000000..fadccccba --- /dev/null +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java @@ -0,0 +1,80 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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 io.netty.handler.codec.http.FullHttpRequest; +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; +import javax.json.JsonObject; +import java.io.StringReader; +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +public class TeraTrackProtocolDecoder extends BaseHttpProtocolDecoder { + + public TeraTrackProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + FullHttpRequest request = (FullHttpRequest) msg; + JsonObject json = Json.createReader( + new StringReader(request.content().toString(StandardCharsets.US_ASCII))).readObject(); + + String deviceId = json.getString("MDeviceID"); + String imei = json.getString("IMEI"); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, deviceId, imei); + if (deviceSession == null) { + sendResponse(channel, HttpResponseStatus.NOT_FOUND); + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + position.setTime(dateFormat.parse(json.getString("DateTime"))); + + position.setValid(true); + + double latitude = Double.parseDouble(json.getString("Latitude")); + position.setLatitude(json.getString("LatitudeState").equals("0") ? -latitude : latitude); + double longitude = Double.parseDouble(json.getString("Longitude")); + position.setLongitude(json.getString("LongitudeState").equals("0") ? -longitude : longitude); + + position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(json.getString("Speed")))); + + position.set(Position.KEY_ODOMETER, Integer.parseInt(json.getString("Mileage"))); + + sendResponse(channel, HttpResponseStatus.OK); + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java new file mode 100644 index 000000000..6ef72dbda --- /dev/null +++ b/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java @@ -0,0 +1,19 @@ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpMethod; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class TeraTrackProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new TeraTrackProtocolDecoder(null); + + verifyAttributes(decoder, request(HttpMethod.POST, "/", + buffer("{\"MDeviceID\":\"074054558620\",\"DeviceType\":\"1\",\"DataType\":\"2\",\"DataLength\":\"0913\",\"DateTime\":\"2022-02-22 23:35:35\",\"Latitude\":\"-6.826699\",\"Longitude\":\"39.279008\",\"LatitudeState\":\"0\",\"LongitudeState\":\"1\",\"Speed\":\"0\",\"Mileage\":\"0\",\"FenceAlarm\":\"0\",\"AreaAlarmID\":\"0\",\"LockCutOff\":\"0\",\"SealTempered\":\"1\",\"MessageAck\":\"1\",\"LockRope\":\"0\",\"LockStatus\":\"0\",\"LockOpen\":\"1\",\"PasswordError\":\"0\",\"CardNo\":\"60060198\",\"IllegalCard\":\"0\",\"LowPower\":\"0\",\"UnCoverBack\":\"1\",\"CoverStatus\":\"0\",\"LockStuck\":\"1\",\"Power\":\"90\",\"GSM\":\"14\",\"IMEI\":\"861774054558620\",\"Index\":\"39\",\"Slave\":[{\"SDeviceId\":\"685304\",\"SPower\":\"00\",\"SLockCutOff\":\"0\",\"SLockOpen\":\"1\",\"SUnCoverBack\":\"0\",\"SCoverStatus\":\"1\",\"STimeOut\":\"1\",\"SLockRope\":\"0\",\"SSealTempered\":\"0\",\"SLockStuck\":\"0\"},{\"SDeviceId\":\"224779\",\"SPower\":\"00\",\"SLockCutOff\":\"0\",\"SLockOpen\":\"1\",\"SUnCoverBack\":\"0\",\"SCoverStatus\":\"1\",\"STimeOut\":\"1\",\"SLockRope\":\"0\",\"SSealTempered\":\"0\",\"SLockStuck\":\"0\"}]}"))); + + } + +} -- cgit v1.2.3 From 18d8ec9610944aee95aa01ffbe402f3d0c30c39a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Mar 2022 18:11:40 -0800 Subject: Fix TeraTrack protocol --- .../java/org/traccar/protocol/TeraTrackProtocolDecoder.java | 13 +++---------- .../org/traccar/protocol/TeraTrackProtocolDecoderTest.java | 5 ++--- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java index fadccccba..7cd678f8a 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java @@ -16,9 +16,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpResponseStatus; -import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; @@ -28,12 +26,11 @@ import javax.json.Json; import javax.json.JsonObject; import java.io.StringReader; import java.net.SocketAddress; -import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.TimeZone; -public class TeraTrackProtocolDecoder extends BaseHttpProtocolDecoder { +public class TeraTrackProtocolDecoder extends BaseProtocolDecoder { public TeraTrackProtocolDecoder(Protocol protocol) { super(protocol); @@ -43,15 +40,12 @@ public class TeraTrackProtocolDecoder extends BaseHttpProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - FullHttpRequest request = (FullHttpRequest) msg; - JsonObject json = Json.createReader( - new StringReader(request.content().toString(StandardCharsets.US_ASCII))).readObject(); + JsonObject json = Json.createReader(new StringReader((String) msg)).readObject(); String deviceId = json.getString("MDeviceID"); String imei = json.getString("IMEI"); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, deviceId, imei); if (deviceSession == null) { - sendResponse(channel, HttpResponseStatus.NOT_FOUND); return null; } @@ -73,7 +67,6 @@ public class TeraTrackProtocolDecoder extends BaseHttpProtocolDecoder { position.set(Position.KEY_ODOMETER, Integer.parseInt(json.getString("Mileage"))); - sendResponse(channel, HttpResponseStatus.OK); return position; } diff --git a/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java index 6ef72dbda..c503e1038 100644 --- a/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java @@ -1,6 +1,5 @@ package org.traccar.protocol; -import io.netty.handler.codec.http.HttpMethod; import org.junit.Test; import org.traccar.ProtocolTest; @@ -11,8 +10,8 @@ public class TeraTrackProtocolDecoderTest extends ProtocolTest { var decoder = new TeraTrackProtocolDecoder(null); - verifyAttributes(decoder, request(HttpMethod.POST, "/", - buffer("{\"MDeviceID\":\"074054558620\",\"DeviceType\":\"1\",\"DataType\":\"2\",\"DataLength\":\"0913\",\"DateTime\":\"2022-02-22 23:35:35\",\"Latitude\":\"-6.826699\",\"Longitude\":\"39.279008\",\"LatitudeState\":\"0\",\"LongitudeState\":\"1\",\"Speed\":\"0\",\"Mileage\":\"0\",\"FenceAlarm\":\"0\",\"AreaAlarmID\":\"0\",\"LockCutOff\":\"0\",\"SealTempered\":\"1\",\"MessageAck\":\"1\",\"LockRope\":\"0\",\"LockStatus\":\"0\",\"LockOpen\":\"1\",\"PasswordError\":\"0\",\"CardNo\":\"60060198\",\"IllegalCard\":\"0\",\"LowPower\":\"0\",\"UnCoverBack\":\"1\",\"CoverStatus\":\"0\",\"LockStuck\":\"1\",\"Power\":\"90\",\"GSM\":\"14\",\"IMEI\":\"861774054558620\",\"Index\":\"39\",\"Slave\":[{\"SDeviceId\":\"685304\",\"SPower\":\"00\",\"SLockCutOff\":\"0\",\"SLockOpen\":\"1\",\"SUnCoverBack\":\"0\",\"SCoverStatus\":\"1\",\"STimeOut\":\"1\",\"SLockRope\":\"0\",\"SSealTempered\":\"0\",\"SLockStuck\":\"0\"},{\"SDeviceId\":\"224779\",\"SPower\":\"00\",\"SLockCutOff\":\"0\",\"SLockOpen\":\"1\",\"SUnCoverBack\":\"0\",\"SCoverStatus\":\"1\",\"STimeOut\":\"1\",\"SLockRope\":\"0\",\"SSealTempered\":\"0\",\"SLockStuck\":\"0\"}]}"))); + verifyAttributes(decoder, text( + "{\"MDeviceID\":\"074054558620\",\"DeviceType\":\"1\",\"DataType\":\"2\",\"DataLength\":\"0913\",\"DateTime\":\"2022-02-22 23:35:35\",\"Latitude\":\"-6.826699\",\"Longitude\":\"39.279008\",\"LatitudeState\":\"0\",\"LongitudeState\":\"1\",\"Speed\":\"0\",\"Mileage\":\"0\",\"FenceAlarm\":\"0\",\"AreaAlarmID\":\"0\",\"LockCutOff\":\"0\",\"SealTempered\":\"1\",\"MessageAck\":\"1\",\"LockRope\":\"0\",\"LockStatus\":\"0\",\"LockOpen\":\"1\",\"PasswordError\":\"0\",\"CardNo\":\"60060198\",\"IllegalCard\":\"0\",\"LowPower\":\"0\",\"UnCoverBack\":\"1\",\"CoverStatus\":\"0\",\"LockStuck\":\"1\",\"Power\":\"90\",\"GSM\":\"14\",\"IMEI\":\"861774054558620\",\"Index\":\"39\",\"Slave\":[{\"SDeviceId\":\"685304\",\"SPower\":\"00\",\"SLockCutOff\":\"0\",\"SLockOpen\":\"1\",\"SUnCoverBack\":\"0\",\"SCoverStatus\":\"1\",\"STimeOut\":\"1\",\"SLockRope\":\"0\",\"SSealTempered\":\"0\",\"SLockStuck\":\"0\"},{\"SDeviceId\":\"224779\",\"SPower\":\"00\",\"SLockCutOff\":\"0\",\"SLockOpen\":\"1\",\"SUnCoverBack\":\"0\",\"SCoverStatus\":\"1\",\"STimeOut\":\"1\",\"SLockRope\":\"0\",\"SSealTempered\":\"0\",\"SLockStuck\":\"0\"}]}")); } -- cgit v1.2.3 From 5b5f99f93324e2e5776523ac9b339d49d5baf031 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 5 Mar 2022 09:08:38 -0800 Subject: Fix frame decoder --- src/main/java/org/traccar/protocol/TeraTrackProtocol.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java index 87d84be44..0303b4b5a 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java @@ -15,9 +15,8 @@ */ 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 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; @@ -28,9 +27,9 @@ public class TeraTrackProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - pipeline.addLast(new HttpResponseEncoder()); - pipeline.addLast(new HttpRequestDecoder()); - pipeline.addLast(new HttpObjectAggregator(65535)); + pipeline.addLast(new JsonFrameDecoder()); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); pipeline.addLast(new TeraTrackProtocolDecoder(TeraTrackProtocol.this)); } }); -- cgit v1.2.3 From 4d0c564b3e8a82de392ad9672c87586d9d24f73c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Mar 2022 13:35:43 -0800 Subject: Update gradle version --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8cf6eb5ad..b1159fc54 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -- cgit v1.2.3 From 09ee3fb9ac865d88f1966cd67fcba67d3c69e390 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Mar 2022 13:53:03 -0800 Subject: Support Wanway S20 format --- .../java/org/traccar/protocol/Gt06ProtocolDecoder.java | 14 +++++++++++--- .../java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index ec09f371b..4d3448e84 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) +Supp * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -712,11 +712,17 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, dateBuilder.getDate()); + boolean hasCellCount = type == MSG_LBS_MULTIPLE_3 && dataLength == 44; + + if (hasCellCount) { + buf.readUnsignedByte(); // ta + } + int mcc = buf.readUnsignedShort(); int mnc = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); Network network = new Network(); - int cellCount = type == MSG_WIFI_5 ? 6 : 7; + int cellCount = hasCellCount ? buf.readUnsignedByte() : type == MSG_WIFI_5 ? 6 : 7; for (int i = 0; i < cellCount; i++) { int lac = longFormat ? buf.readInt() : buf.readUnsignedShort(); int cid = longFormat ? (int) buf.readLong() : buf.readUnsignedMedium(); @@ -726,7 +732,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - buf.readUnsignedByte(); // time leads + if (!hasCellCount) { + buf.readUnsignedByte(); // ta + } if (type != MSG_LBS_MULTIPLE_1 && type != MSG_LBS_MULTIPLE_2 && type != MSG_LBS_MULTIPLE_3 && type != MSG_LBS_2) { diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 8aadb7fe3..ad65ec960 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyNotNull(decoder, binary( + "787831241603060c231e000194620213ee00606a3413ee0060692e000000000000000000000000000000000000000000003a0cb70d0a")); + verifyNotNull(decoder, binary( "78783B2810010D02020201CC00287D001F713E287D001F7231287D001E232D287D001F4018000000000000000000000000000000000000FF00020005B14B0D0A")); -- cgit v1.2.3 From 90dd949c149c4acf9bc383dd019a595808be928e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Mar 2022 15:34:21 -0800 Subject: Decode TK419-S cell and wifi --- .../traccar/protocol/EelinkProtocolDecoder.java | 46 ++++++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index 9856ad999..592e5a56c 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -31,6 +31,7 @@ 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.nio.charset.StandardCharsets; @@ -192,50 +193,69 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, position.getDeviceTime()); } + Network network = new Network(); + + int mcc = 0; + int mnc = 0; if (BitUtil.check(flags, 1)) { - position.setNetwork(new Network(CellTower.from( - buf.readUnsignedShort(), buf.readUnsignedShort(), - buf.readUnsignedShort(), buf.readUnsignedInt(), buf.readUnsignedByte()))); + mcc = buf.readUnsignedShort(); + mnc = buf.readUnsignedShort(); + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedInt(), buf.readUnsignedByte())); } if (BitUtil.check(flags, 2)) { - buf.skipBytes(7); // bsid1 + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedInt(), buf.readUnsignedByte())); } if (BitUtil.check(flags, 3)) { - buf.skipBytes(7); // bsid2 + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedInt(), buf.readUnsignedByte())); } if (BitUtil.check(flags, 4)) { - buf.skipBytes(7); // bss0 + String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); } if (BitUtil.check(flags, 5)) { - buf.skipBytes(7); // bss1 + String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); } if (BitUtil.check(flags, 6)) { - buf.skipBytes(7); // bss2 + String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); } if (BitUtil.check(flags, 7)) { buf.readUnsignedByte(); // radio access technology int count = buf.readUnsignedByte(); + int lac = 0; if (count > 0) { - buf.readUnsignedShort(); // mcc - buf.readUnsignedShort(); // mnc - buf.readUnsignedShort(); // lac + mcc = buf.readUnsignedShort(); + mnc = buf.readUnsignedShort(); + lac = buf.readUnsignedShort(); // lac buf.readUnsignedShort(); // tac buf.readUnsignedInt(); // cid buf.readUnsignedShort(); // ta } for (int i = 0; i < count; i++) { - buf.readUnsignedShort(); // physical cid + int cid = buf.readUnsignedShort(); // physical cid buf.readUnsignedShort(); // e-arfcn - buf.readUnsignedByte(); // rssi + int rssi = buf.readUnsignedByte(); + network.addCellTower(CellTower.from(mcc, mnc, lac, cid, rssi)); } } + if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { + position.setNetwork(network); + } + if (type == MSG_WARNING) { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); -- cgit v1.2.3 From e5377cf87d3153f6f33bf20e48af1a2431ee052e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Mar 2022 15:40:46 -0800 Subject: Simplify device model --- src/main/java/org/traccar/model/Device.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 836a6709c..219f078ed 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,20 +64,12 @@ public class Device extends GroupedModel { private Date lastUpdate; public Date getLastUpdate() { - if (lastUpdate != null) { - return new Date(lastUpdate.getTime()); - } else { - return null; - } + return this.lastUpdate; } @QueryExtended public void setLastUpdate(Date lastUpdate) { - if (lastUpdate != null) { - this.lastUpdate = new Date(lastUpdate.getTime()); - } else { - this.lastUpdate = null; - } + this.lastUpdate = lastUpdate; } private long positionId; -- cgit v1.2.3 From 5f007edebf88afb353f26310645639e051a53c0e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Mar 2022 15:57:54 -0800 Subject: Revert "Remove unnecessary file" This reverts commit 4b4201de3519ce744dcbba303bd10aaaa4d3fa7b. --- .../java/org/traccar/api/ObjectMapperProvider.java | 32 ++++++++++++++++++++++ src/main/java/org/traccar/web/WebServer.java | 3 +- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/traccar/api/ObjectMapperProvider.java diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java new file mode 100644 index 000000000..f81b20917 --- /dev/null +++ b/src/main/java/org/traccar/api/ObjectMapperProvider.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015 - 2016 Anton Tananaev (anton@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.api; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.traccar.Context; + +import javax.ws.rs.ext.ContextResolver; +import javax.ws.rs.ext.Provider; + +@Provider +public class ObjectMapperProvider implements ContextResolver { + + @Override + public ObjectMapper getContext(Class type) { + return Context.getObjectMapper(); + } + +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 0364972d7..932781156 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -52,6 +52,7 @@ import org.traccar.config.Config; import org.traccar.api.AsyncSocketServlet; import org.traccar.api.CorsResponseFilter; import org.traccar.api.MediaFilter; +import org.traccar.api.ObjectMapperProvider; import org.traccar.api.ResourceErrorHandler; import org.traccar.api.security.SecurityRequestFilter; import org.traccar.api.resource.ServerResource; @@ -176,7 +177,7 @@ public class WebServer { ResourceConfig resourceConfig = new ResourceConfig(); resourceConfig.registerClasses( - JacksonFeature.class, ResourceErrorHandler.class, + JacksonFeature.class, ObjectMapperProvider.class, ResourceErrorHandler.class, SecurityRequestFilter.class, CorsResponseFilter.class, DateParameterConverterProvider.class); resourceConfig.packages(ServerResource.class.getPackage().getName()); resourceConfig.register(new ContainerLifecycleListener() { -- cgit v1.2.3 From 9d0682014dd293139a56b3d08e76469a726efebd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 8 Mar 2022 18:36:44 -0800 Subject: Fix TeraTrack coordinates decoding --- src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java index 7cd678f8a..8f4438fbb 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java @@ -57,12 +57,8 @@ public class TeraTrackProtocolDecoder extends BaseProtocolDecoder { position.setTime(dateFormat.parse(json.getString("DateTime"))); position.setValid(true); - - double latitude = Double.parseDouble(json.getString("Latitude")); - position.setLatitude(json.getString("LatitudeState").equals("0") ? -latitude : latitude); - double longitude = Double.parseDouble(json.getString("Longitude")); - position.setLongitude(json.getString("LongitudeState").equals("0") ? -longitude : longitude); - + position.setLatitude(Double.parseDouble(json.getString("Latitude"))); + position.setLongitude(Double.parseDouble(json.getString("Longitude"))); position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(json.getString("Speed")))); position.set(Position.KEY_ODOMETER, Integer.parseInt(json.getString("Mileage"))); -- cgit v1.2.3 From 0e85fafea121b912e20e022e423b6b472a2e93be Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 9 Mar 2022 09:14:55 -0800 Subject: Fix FlexApi frame decoding --- src/main/java/org/traccar/protocol/FlexApiProtocol.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java index bc6a49907..7f4154f71 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -21,6 +21,8 @@ import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import java.nio.charset.StandardCharsets; + public class FlexApiProtocol extends BaseProtocol { public FlexApiProtocol() { @@ -28,7 +30,7 @@ public class FlexApiProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LineBasedFrameDecoder(5120)); - pipeline.addLast(new StringDecoder()); + pipeline.addLast(new StringDecoder(StandardCharsets.US_ASCII)); pipeline.addLast(new FlexApiProtocolDecoder(FlexApiProtocol.this)); } }); -- cgit v1.2.3 From 35c2316a12113b29f00fa5ad735e59a88494c8bb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 9 Mar 2022 18:39:54 -0800 Subject: Decode additional TeraTrack info --- src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java | 5 +++++ src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java index 8f4438fbb..634c18bcb 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java @@ -62,6 +62,11 @@ public class TeraTrackProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(json.getString("Speed")))); position.set(Position.KEY_ODOMETER, Integer.parseInt(json.getString("Mileage"))); + position.set(Position.KEY_BLOCKED, json.getString("LockOpen").equals("0")); + position.set(Position.KEY_DRIVER_UNIQUE_ID, json.getString("CardNo")); + position.set(Position.KEY_ALARM, json.getString("LowPower").equals("1") ? Position.ALARM_LOW_POWER : null); + position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(json.getString("Power"))); + position.set(Position.KEY_RSSI, Integer.parseInt(json.getString("GSM"))); return position; } diff --git a/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java index c503e1038..6f96f73ad 100644 --- a/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TeraTrackProtocolDecoderTest extends ProtocolTest { var decoder = new TeraTrackProtocolDecoder(null); + verifyAttributes(decoder, text( + "{\"MDeviceID\":\"022043756090\",\"DiviceType\":\"1\",\"DataType\":\"1\",\"DataLength\":\"69\",\"DateTime\":\"2022-03-09 10:56:01\",\"Latitude\":\"-6.846451\",\"Longitude\":\"39.316324\",\"LongitudeState\":\"1\",\"LatitudeState\":\"0\",\"Speed\":\"90\",\"Mileage\":\"0\",\"FenceAlarm\":\"0\",\"AreaAlarmID\":\"0\",\"LockCutOff\":\"0\",\"SealTampered\":\"0\",\"MessageAck\":\"1\",\"LockRope\":\"1\",\"LockStatus\":\"1\",\"LockOpen\":\"0\",\"PasswordError\":\"0\",\"CardNo\":\"60000644\",\"IllegalCard\":\"0\",\"LowPower\":\"0\",\"UnCoverBack\":\"0\",\"CoverStatus\":\"1\",\"LockStuck\":\"0\",\"Power\":\"79\",\"GSM\":\"16\",\"IMEI\":\"860922043756090\",\"Index\":\"20\",\"Slave\":[]}")); + verifyAttributes(decoder, text( "{\"MDeviceID\":\"074054558620\",\"DeviceType\":\"1\",\"DataType\":\"2\",\"DataLength\":\"0913\",\"DateTime\":\"2022-02-22 23:35:35\",\"Latitude\":\"-6.826699\",\"Longitude\":\"39.279008\",\"LatitudeState\":\"0\",\"LongitudeState\":\"1\",\"Speed\":\"0\",\"Mileage\":\"0\",\"FenceAlarm\":\"0\",\"AreaAlarmID\":\"0\",\"LockCutOff\":\"0\",\"SealTempered\":\"1\",\"MessageAck\":\"1\",\"LockRope\":\"0\",\"LockStatus\":\"0\",\"LockOpen\":\"1\",\"PasswordError\":\"0\",\"CardNo\":\"60060198\",\"IllegalCard\":\"0\",\"LowPower\":\"0\",\"UnCoverBack\":\"1\",\"CoverStatus\":\"0\",\"LockStuck\":\"1\",\"Power\":\"90\",\"GSM\":\"14\",\"IMEI\":\"861774054558620\",\"Index\":\"39\",\"Slave\":[{\"SDeviceId\":\"685304\",\"SPower\":\"00\",\"SLockCutOff\":\"0\",\"SLockOpen\":\"1\",\"SUnCoverBack\":\"0\",\"SCoverStatus\":\"1\",\"STimeOut\":\"1\",\"SLockRope\":\"0\",\"SSealTempered\":\"0\",\"SLockStuck\":\"0\"},{\"SDeviceId\":\"224779\",\"SPower\":\"00\",\"SLockCutOff\":\"0\",\"SLockOpen\":\"1\",\"SUnCoverBack\":\"0\",\"SCoverStatus\":\"1\",\"STimeOut\":\"1\",\"SLockRope\":\"0\",\"SSealTempered\":\"0\",\"SLockStuck\":\"0\"}]}")); -- cgit v1.2.3 From 143a51790b613831e455d49299098d97aff34bfa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 10 Mar 2022 19:42:51 -0800 Subject: Decode ORBCOMM event time --- src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index e7ea87428..7277b1e5f 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -33,6 +33,7 @@ import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Date; import java.util.LinkedList; import java.util.TimeZone; @@ -85,6 +86,9 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { JsonObject field = fields.getJsonObject(j); String value = field.getString("Value"); switch (field.getString("Name").toLowerCase()) { + case "eventtime": + position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); + break; case "latitude": position.setLatitude(Integer.parseInt(value) / 60000.0); break; -- cgit v1.2.3 From b0b9cdb254eb5031c744be1029d87aaf2802b674 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 18 Mar 2022 17:02:42 -0700 Subject: Handle heartbeat messages (fix #4824) --- src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java | 9 +++++++-- .../java/org/traccar/protocol/NavtelecomFrameDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java index 0fb82528b..2ab7d11a9 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@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,12 @@ public class NavtelecomFrameDecoder extends BaseFrameDecoder { protected Object decode( ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - if (buf.getByte(buf.readerIndex()) == '@') { + if (buf.getByte(buf.readerIndex()) == 0x7f) { + + buf.skipBytes(1); + return null; + + } else if (buf.getByte(buf.readerIndex()) == '@') { int length = buf.getUnsignedShortLE(12) + 12 + 2 + 2; if (buf.readableBytes() >= length) { diff --git a/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java index 07b19651b..562b220d4 100644 --- a/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java @@ -19,6 +19,9 @@ public class NavtelecomFrameDecoderTest extends ProtocolTest { binary("404e544301000000000000002a005e6c2a3e464c4558b01e1efffffe300a08080ffffe08000000580028002bc0000000000000b4000000000000"), decoder.decode(null, null, binary("404e544301000000000000002a005e6c2a3e464c4558b01e1efffffe300a08080ffffe08000000580028002bc0000000000000b4000000000000"))); + verifyNull( + decoder.decode(null, null, binary("7f"))); + } @Ignore -- cgit v1.2.3 From bcb2eb7db5f34cf1aa25024fa41f226f7d99a0c7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 18 Mar 2022 20:37:47 -0700 Subject: Add TeraTrack response --- src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java index 634c18bcb..c36da2aed 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java @@ -18,6 +18,7 @@ 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.UnitsConverter; import org.traccar.model.Position; @@ -68,6 +69,10 @@ public class TeraTrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(json.getString("Power"))); position.set(Position.KEY_RSSI, Integer.parseInt(json.getString("GSM"))); + if (channel != null && json.getString("MessageAck").equals("1")) { + channel.writeAndFlush(new NetworkMessage("{01}", remoteAddress)); + } + return position; } -- cgit v1.2.3 From 64b5b53e47b08088f832556f5ce3e10a36fc4420 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 20 Mar 2022 11:15:32 -0700 Subject: Add Xexun2 test case --- src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java index 89c499016..9faccec01 100644 --- a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Xexun2ProtocolDecoderTest extends ProtocolTest { var decoder = new Xexun2ProtocolDecoder(null); + verifyPositions(decoder, false, binary( + "faaf00140a5a8618810536243350005ed8e101005b64622880401b001482060864cc2296f840daa22aa884f008c87483c291efddc4f09fc2f49db3c058ef68005a9abe1ae8299d6449bac4e984e0c1d6baa8469d265ff2b60100cc00080000fb2e0013572a3600000002000000000000faaf")); + verifyPositions(decoder, false, binary( "FAAF00140004863921033475388000AFB7D203003800380038F9608A7B801E0060820205788A205DF523D97844FDB90443D37844FDB90465CFB4FBF946B0E8CEF639095803F8CC00000002350000004000FA608A7BA81E0060820205788A205DF523D97844FDB90443D2F639095803F8CFB4FBF946B0E8CE7844FDB90465CD00000002350000004000FB608A7BD01E0060820205788A205DF523D97844FDB90443D2F639095803F8CFB4FBF946B0E8CE7844FDB90465CD00000002350000004000FAAF")); -- cgit v1.2.3 From a9e3ac7b143e848398fda8f8fb06709d334b6212 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 20 Mar 2022 21:13:21 -0700 Subject: Update gradle and wrapper --- gradle/wrapper/gradle-wrapper.jar | Bin 58695 -> 59821 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 257 ++++++++++++++++++------------- gradlew.bat | 25 +-- 4 files changed, 162 insertions(+), 122 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index f3d88b1c2..41d9927a4 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b1159fc54..00e33edef 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 2fe81a7d9..1b6c78733 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,78 +17,113 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -105,79 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 9618d8d96..107acd32c 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @@ -37,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -51,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -61,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell -- cgit v1.2.3 From 2fcf8ea7ed086175658d05e536d4ce071cf17dda Mon Sep 17 00:00:00 2001 From: Yuriy Date: Tue, 22 Mar 2022 11:36:01 +0300 Subject: Decode additional Navtelecom info --- .../protocol/NavtelecomProtocolDecoder.java | 162 ++++++++++++++++++++- 1 file changed, 161 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 5d3a81f2a..72a74a534 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -195,6 +195,9 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { for (int j = 0; j < bits.length(); j++) { if (bits.get(j)) { + + int tmp = 0; // To parse a value by multiple conditions + switch (j + 1) { case 1: position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); @@ -205,8 +208,12 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 3: position.setDeviceTime(new Date(buf.readUnsignedIntLE() * 1000)); break; + case 8: + tmp = buf.readUnsignedByte(); + position.setValid((tmp & 0b00000010) == 0b00000010); + position.set(Position.KEY_SATELLITES, ((tmp & 0b11111100) >> 2)); + break; case 9: - position.setValid(true); position.setFixTime(new Date(buf.readUnsignedIntLE() * 1000)); break; case 10: @@ -221,6 +228,159 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 13: position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE())); break; + case 14: + position.setCourse(buf.readUnsignedShortLE()); + break; + case 15: + position.set(Position.KEY_ODOMETER,buf.readFloatLE()); + break; + case 19: + position.set(Position.KEY_POWER,buf.readShortLE() * 0.001); + break; + case 20: + position.set(Position.KEY_BATTERY,buf.readShortLE() * 0.001); + break; + case 21: + position.set(Position.PREFIX_ADC + 1,buf.readUnsignedShortLE() * 0.001); + break; + case 22: + position.set(Position.PREFIX_ADC + 2,buf.readUnsignedShortLE() * 0.001); + break; + case 23: + position.set(Position.PREFIX_ADC + 3,buf.readUnsignedShortLE() * 0.001); + break; + case 24: + position.set(Position.PREFIX_ADC + 4,buf.readUnsignedShortLE() * 0.001); + break; + case 25: + position.set(Position.PREFIX_ADC + 5,buf.readUnsignedShortLE() * 0.001); + break; + case 26: + position.set(Position.PREFIX_ADC + 6,buf.readUnsignedShortLE() * 0.001); + break; + case 29: + tmp = buf.readUnsignedByte(); + position.set(Position.PREFIX_IN + 1, (tmp & 0b00000001) == 0b00000001); + position.set(Position.PREFIX_IN + 2, (tmp & 0b00000010) == 0b00000010); + position.set(Position.PREFIX_IN + 3, (tmp & 0b00000100) == 0b00000100); + position.set(Position.PREFIX_IN + 4, (tmp & 0b00001000) == 0b00001000); + position.set(Position.PREFIX_IN + 5, (tmp & 0b00010000) == 0b00010000); + position.set(Position.PREFIX_IN + 6, (tmp & 0b00100000) == 0b00100000); + position.set(Position.PREFIX_IN + 7, (tmp & 0b01000000) == 0b01000000); + position.set(Position.PREFIX_IN + 8, (tmp & 0b10000000) == 0b10000000); + break; + case 31: + tmp = buf.readUnsignedByte(); + position.set(Position.PREFIX_OUT + 1, (tmp & 0b00000001) == 0b00000001); + position.set(Position.PREFIX_OUT + 2, (tmp & 0b00000010) == 0b00000010); + position.set(Position.PREFIX_OUT + 3, (tmp & 0b00000100) == 0b00000100); + position.set(Position.PREFIX_OUT + 4, (tmp & 0b00001000) == 0b00001000); + break; + case 33: + position.set(Position.PREFIX_COUNT + 1,buf.readUnsignedIntLE()); + break; + case 34: + position.set(Position.PREFIX_COUNT + 2,buf.readUnsignedIntLE()); + break; + case 35: + position.set("freq" + 1,buf.readUnsignedShortLE()); + break; + case 36: + position.set("freq" + 2,buf.readUnsignedShortLE()); + break; + case 37: + position.set("engine_hours",buf.readUnsignedIntLE()); + break; + case 38: + tmp = buf.readUnsignedShortLE(); + if (tmp < 65500) { // Do not write error codes + position.set("rs485fuel_level" + 1,tmp); + } + break; + case 39: + tmp = buf.readUnsignedShortLE(); + if (tmp < 65500) { // Do not write error codes + position.set("rs485fuel_level" + 2,tmp); + } + break; + case 40: + tmp = buf.readUnsignedShortLE(); + if (tmp < 65500) { // Do not write error codes + position.set("rs485fuel_level" + 3,tmp); + } + break; + case 41: + tmp = buf.readUnsignedShortLE(); + if (tmp < 65500) { // Do not write error codes + position.set("rs485fuel_level" + 4,tmp); + } + break; + case 42: + tmp = buf.readUnsignedShortLE(); + if (tmp < 65500) { // Do not write error codes + position.set("rs485fuel_level" + 5,tmp); + } + break; + case 43: + tmp = buf.readUnsignedShortLE(); + if (tmp < 65500) { // Do not write error codes + position.set("rs485fuel_level" + 6,tmp); + } + break; + case 44: + tmp = buf.readUnsignedShortLE(); + if (tmp < 65500) { // Do not write error codes + position.set("rs232fuel_level",tmp); + } + break; + case 45: + tmp = buf.readByte(); + if (tmp != 0x80) { // Do not write error codes + position.set(Position.PREFIX_TEMP + 1,tmp); + } + break; + case 46: + tmp = buf.readByte(); + if (tmp != 0x80) { // Do not write error codes + position.set(Position.PREFIX_TEMP + 2,tmp); + } + break; + case 47: + tmp = buf.readByte(); + if (tmp != 0x80) { // Do not write error codes + position.set(Position.PREFIX_TEMP + 3,tmp); + } + break; + case 48: + tmp = buf.readByte(); + if (tmp != 0x80) { // Do not write error codes + position.set(Position.PREFIX_TEMP + 4,tmp); + } + break; + case 49: + tmp = buf.readByte(); + if (tmp != 0x80) { // Do not write error codes + position.set(Position.PREFIX_TEMP + 5,tmp); + } + break; + case 50: + tmp = buf.readByte(); + if (tmp != 0x80) { // Do not write error codes + position.set(Position.PREFIX_TEMP + 6,tmp); + } + break; + case 51: + tmp = buf.readByte(); + if (tmp != 0x80) { // Do not write error codes + position.set(Position.PREFIX_TEMP + 7,tmp); + } + break; + case 52: + tmp = buf.readByte(); + if (tmp != 0x80) { // Do not write error codes + position.set(Position.PREFIX_TEMP + 8,tmp); + } + break; default: buf.skipBytes(getItemLength(j + 1)); break; -- cgit v1.2.3 From f5033ee29a955796fb4c911f83e3d8253c98e62e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 22 Mar 2022 13:52:26 -0700 Subject: Handle Wialon missing data --- .../java/org/traccar/protocol/WialonProtocolDecoder.java | 14 +++++++++----- .../org/traccar/protocol/WialonProtocolDecoderTest.java | 3 +++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 80299ff08..19d9dd6c8 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,13 +47,13 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { .compile(); private static final Pattern PATTERN = new PatternBuilder() - .number("(dd)(dd)(dd);") // date (ddmmyy) - .number("(dd)(dd)(dd);") // time (hhmmss) + .number("(?:NA|(dd)(dd)(dd));") // date (ddmmyy) + .number("(?:NA|(dd)(dd)(dd));") // time (hhmmss) .number("(?:NA|(dd)(dd.d+));") // latitude .expression("(?:NA|([NS]));") .number("(?:NA|(ddd)(dd.d+));") // longitude .expression("(?:NA|([EW]));") - .number("(d+.?d*)?;") // speed + .number("(?:NA|(d+.?d*))?;") // speed .number("(?:NA|(d+.?d*))?;") // course .number("(?:NA|(-?d+.?d*));") // altitude .number("(?:NA|(d+))") // satellites @@ -95,7 +95,11 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + if (parser.hasNext(6)) { + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + } else { + position.setTime(new Date()); + } if (parser.hasNext(9)) { position.setLatitude(parser.nextCoordinate()); diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java index 7387f5325..12724c32f 100644 --- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class WialonProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "#L#2.0;42001300083;;CE45")); + verifyAttributes(decoder, text( + "#D#NA;NA;5429.681944502211763;N;02654.60403650999069;E;NA;NA;NA;NA;NA;NA;NA;1.0;NA;m1:1:9196679,d1:1:15397,t1:1:20,b1:1:162,fuel1:2:21588.0,pv1:2:35.98,finish:1:1;0x9b0")); + verifyAttributes(decoder, text( "#D#120319;112003;NA;NA;NA;NA;0.000;NA;NA;0;NA;NA;NA;NA;NA;101_521347:1:521246,101_158:1:510,101_521055:1:510,101_521055_2.9:1:509,101_521056:1:3;626B")); -- cgit v1.2.3 From 93e9d449d187bc3947ca76a1f3bdd4f02b37752c Mon Sep 17 00:00:00 2001 From: Yuriy Piskarev Date: Wed, 23 Mar 2022 15:46:37 +0300 Subject: - fixed warnings from checkstyle; - rename tmp variable; - added use of BitUtil; - redesigned parameter checking; --- .../protocol/NavtelecomProtocolDecoder.java | 148 ++++++++------------- 1 file changed, 56 insertions(+), 92 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 72a74a534..d4026353d 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -196,7 +196,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { for (int j = 0; j < bits.length(); j++) { if (bits.get(j)) { - int tmp = 0; // To parse a value by multiple conditions + int value = 0; switch (j + 1) { case 1: @@ -209,9 +209,9 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { position.setDeviceTime(new Date(buf.readUnsignedIntLE() * 1000)); break; case 8: - tmp = buf.readUnsignedByte(); - position.setValid((tmp & 0b00000010) == 0b00000010); - position.set(Position.KEY_SATELLITES, ((tmp & 0b11111100) >> 2)); + value = buf.readUnsignedByte(); + position.setValid(BitUtil.check(value, 1)); + position.set(Position.KEY_SATELLITES, ((value & 0b11111100) >> 2)); break; case 9: position.setFixTime(new Date(buf.readUnsignedIntLE() * 1000)); @@ -232,154 +232,118 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { position.setCourse(buf.readUnsignedShortLE()); break; case 15: - position.set(Position.KEY_ODOMETER,buf.readFloatLE()); + position.set(Position.KEY_ODOMETER, buf.readFloatLE()); break; case 19: - position.set(Position.KEY_POWER,buf.readShortLE() * 0.001); + position.set(Position.KEY_POWER, buf.readShortLE() * 0.001); break; case 20: - position.set(Position.KEY_BATTERY,buf.readShortLE() * 0.001); + position.set(Position.KEY_BATTERY, buf.readShortLE() * 0.001); break; case 21: - position.set(Position.PREFIX_ADC + 1,buf.readUnsignedShortLE() * 0.001); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE() * 0.001); break; case 22: - position.set(Position.PREFIX_ADC + 2,buf.readUnsignedShortLE() * 0.001); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE() * 0.001); break; case 23: - position.set(Position.PREFIX_ADC + 3,buf.readUnsignedShortLE() * 0.001); + position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShortLE() * 0.001); break; case 24: - position.set(Position.PREFIX_ADC + 4,buf.readUnsignedShortLE() * 0.001); + position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShortLE() * 0.001); break; case 25: - position.set(Position.PREFIX_ADC + 5,buf.readUnsignedShortLE() * 0.001); + position.set(Position.PREFIX_ADC + 5, buf.readUnsignedShortLE() * 0.001); break; case 26: - position.set(Position.PREFIX_ADC + 6,buf.readUnsignedShortLE() * 0.001); + position.set(Position.PREFIX_ADC + 6, buf.readUnsignedShortLE() * 0.001); break; case 29: - tmp = buf.readUnsignedByte(); - position.set(Position.PREFIX_IN + 1, (tmp & 0b00000001) == 0b00000001); - position.set(Position.PREFIX_IN + 2, (tmp & 0b00000010) == 0b00000010); - position.set(Position.PREFIX_IN + 3, (tmp & 0b00000100) == 0b00000100); - position.set(Position.PREFIX_IN + 4, (tmp & 0b00001000) == 0b00001000); - position.set(Position.PREFIX_IN + 5, (tmp & 0b00010000) == 0b00010000); - position.set(Position.PREFIX_IN + 6, (tmp & 0b00100000) == 0b00100000); - position.set(Position.PREFIX_IN + 7, (tmp & 0b01000000) == 0b01000000); - position.set(Position.PREFIX_IN + 8, (tmp & 0b10000000) == 0b10000000); + value = buf.readUnsignedByte(); + for (int k = 0; k <= 7; k++) { + position.set(Position.PREFIX_IN + (k + 1), BitUtil.check(value, k) ? 1 : 0); + } break; case 31: - tmp = buf.readUnsignedByte(); - position.set(Position.PREFIX_OUT + 1, (tmp & 0b00000001) == 0b00000001); - position.set(Position.PREFIX_OUT + 2, (tmp & 0b00000010) == 0b00000010); - position.set(Position.PREFIX_OUT + 3, (tmp & 0b00000100) == 0b00000100); - position.set(Position.PREFIX_OUT + 4, (tmp & 0b00001000) == 0b00001000); + value = buf.readUnsignedByte(); + for (int k = 0; k <= 3; k++) { + position.set(Position.PREFIX_OUT + (k + 1), BitUtil.check(value, k) ? 1 : 0); + } break; case 33: - position.set(Position.PREFIX_COUNT + 1,buf.readUnsignedIntLE()); + position.set(Position.PREFIX_COUNT + 1, buf.readUnsignedIntLE()); break; case 34: - position.set(Position.PREFIX_COUNT + 2,buf.readUnsignedIntLE()); + position.set(Position.PREFIX_COUNT + 2, buf.readUnsignedIntLE()); break; case 35: - position.set("freq" + 1,buf.readUnsignedShortLE()); + position.set("freq" + 1, buf.readUnsignedShortLE()); break; case 36: - position.set("freq" + 2,buf.readUnsignedShortLE()); + position.set("freq" + 2, buf.readUnsignedShortLE()); break; case 37: - position.set("engine_hours",buf.readUnsignedIntLE()); + position.set("engine_hours", buf.readUnsignedIntLE()); break; case 38: - tmp = buf.readUnsignedShortLE(); - if (tmp < 65500) { // Do not write error codes - position.set("rs485fuel_level" + 1,tmp); - } + value = buf.readUnsignedShortLE(); + position.set("rs485fuel_level" + 1, (value < 65500) ? value : null); break; case 39: - tmp = buf.readUnsignedShortLE(); - if (tmp < 65500) { // Do not write error codes - position.set("rs485fuel_level" + 2,tmp); - } + value = buf.readUnsignedShortLE(); + position.set("rs485fuel_level" + 2, (value < 65500) ? value : null); break; case 40: - tmp = buf.readUnsignedShortLE(); - if (tmp < 65500) { // Do not write error codes - position.set("rs485fuel_level" + 3,tmp); - } + value = buf.readUnsignedShortLE(); + position.set("rs485fuel_level" + 3, (value < 65500) ? value : null); break; case 41: - tmp = buf.readUnsignedShortLE(); - if (tmp < 65500) { // Do not write error codes - position.set("rs485fuel_level" + 4,tmp); - } + value = buf.readUnsignedShortLE(); + position.set("rs485fuel_level" + 4, (value < 65500) ? value : null); break; case 42: - tmp = buf.readUnsignedShortLE(); - if (tmp < 65500) { // Do not write error codes - position.set("rs485fuel_level" + 5,tmp); - } + value = buf.readUnsignedShortLE(); + position.set("rs485fuel_level" + 5, (value < 65500) ? value : null); break; case 43: - tmp = buf.readUnsignedShortLE(); - if (tmp < 65500) { // Do not write error codes - position.set("rs485fuel_level" + 6,tmp); - } + value = buf.readUnsignedShortLE(); + position.set("rs485fuel_level" + 6, (value < 65500) ? value : null); break; case 44: - tmp = buf.readUnsignedShortLE(); - if (tmp < 65500) { // Do not write error codes - position.set("rs232fuel_level",tmp); - } + value = buf.readUnsignedShortLE(); + position.set("rs232fuel_level", (value < 65500) ? value : null); break; case 45: - tmp = buf.readByte(); - if (tmp != 0x80) { // Do not write error codes - position.set(Position.PREFIX_TEMP + 1,tmp); - } + value = buf.readByte(); + position.set(Position.PREFIX_TEMP + 1, (value != 0x80) ? value : null); break; case 46: - tmp = buf.readByte(); - if (tmp != 0x80) { // Do not write error codes - position.set(Position.PREFIX_TEMP + 2,tmp); - } + value = buf.readByte(); + position.set(Position.PREFIX_TEMP + 2, (value != 0x80) ? value : null); break; case 47: - tmp = buf.readByte(); - if (tmp != 0x80) { // Do not write error codes - position.set(Position.PREFIX_TEMP + 3,tmp); - } + value = buf.readByte(); + position.set(Position.PREFIX_TEMP + 3, (value != 0x80) ? value : null); break; case 48: - tmp = buf.readByte(); - if (tmp != 0x80) { // Do not write error codes - position.set(Position.PREFIX_TEMP + 4,tmp); - } + value = buf.readByte(); + position.set(Position.PREFIX_TEMP + 4, (value != 0x80) ? value : null); break; case 49: - tmp = buf.readByte(); - if (tmp != 0x80) { // Do not write error codes - position.set(Position.PREFIX_TEMP + 5,tmp); - } + value = buf.readByte(); + position.set(Position.PREFIX_TEMP + 5, (value != 0x80) ? value : null); break; case 50: - tmp = buf.readByte(); - if (tmp != 0x80) { // Do not write error codes - position.set(Position.PREFIX_TEMP + 6,tmp); - } + value = buf.readByte(); + position.set(Position.PREFIX_TEMP + 6, (value != 0x80) ? value : null); break; case 51: - tmp = buf.readByte(); - if (tmp != 0x80) { // Do not write error codes - position.set(Position.PREFIX_TEMP + 7,tmp); - } + value = buf.readByte(); + position.set(Position.PREFIX_TEMP + 7, (value != 0x80) ? value : null); break; case 52: - tmp = buf.readByte(); - if (tmp != 0x80) { // Do not write error codes - position.set(Position.PREFIX_TEMP + 8,tmp); - } + value = buf.readByte(); + position.set(Position.PREFIX_TEMP + 8, (value != 0x80) ? value : null); break; default: buf.skipBytes(getItemLength(j + 1)); -- cgit v1.2.3 From 2c5d65c30159b620eebce8dd7b8a768c06271031 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 23 Mar 2022 10:24:47 -0700 Subject: Fix TK915-4GSA decoding --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 11 ++++++++--- .../java/org/traccar/protocol/WatchProtocolDecoderTest.java | 3 +++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index cf58b0fed..4ab7875b7 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -149,9 +149,14 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; for (int i = 0; i < cellCount; i++) { - network.addCellTower(CellTower.from(mcc, mnc, - Integer.parseInt(values[index++]), Integer.parseInt(values[index++]), - Integer.parseInt(values[index++]))); + int lac = Integer.parseInt(values[index++]); + int cid = Integer.parseInt(values[index++]); + String rssi = values[index++]; + if (!rssi.isEmpty()) { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(rssi))); + } else { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + } } if (index < values.length && !values[index].isEmpty()) { diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 98e83f491..4fab19f26 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -19,6 +19,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { "[3G*2104326058*000E*btemp2,1,35.29]"), Position.PREFIX_TEMP + 1, 35.29); + verifyPosition(decoder, buffer( + "[SG*9159059735*0066*UD2,230322,082138,A,59.55285,N,016.66185,E,0.0,000,26,14,80,70,0,50,00000000,1,1,240,7,34505,80806406,,00]")); + verifyPosition(decoder, buffer( "[SG*9059056143*0053*UD,251021,223408,A,41.46500,N,081.53128,W,0.926,000,0,00,70,70,0,50,00000000,0,1,,,,00]")); -- cgit v1.2.3 From 43c35020d55f552157f53a28bfd3bec765e387ab Mon Sep 17 00:00:00 2001 From: Yuriy Piskarev Date: Thu, 24 Mar 2022 13:25:50 +0300 Subject: - rename fuel key; --- .../org/traccar/protocol/NavtelecomProtocolDecoder.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index d4026353d..ff6f12dde 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -287,31 +287,31 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { break; case 38: value = buf.readUnsignedShortLE(); - position.set("rs485fuel_level" + 1, (value < 65500) ? value : null); + position.set("rs485Fuel" + 1, (value < 65500) ? value : null); break; case 39: value = buf.readUnsignedShortLE(); - position.set("rs485fuel_level" + 2, (value < 65500) ? value : null); + position.set("rs485Fuel" + 2, (value < 65500) ? value : null); break; case 40: value = buf.readUnsignedShortLE(); - position.set("rs485fuel_level" + 3, (value < 65500) ? value : null); + position.set("rs485Fuel" + 3, (value < 65500) ? value : null); break; case 41: value = buf.readUnsignedShortLE(); - position.set("rs485fuel_level" + 4, (value < 65500) ? value : null); + position.set("rs485Fuel" + 4, (value < 65500) ? value : null); break; case 42: value = buf.readUnsignedShortLE(); - position.set("rs485fuel_level" + 5, (value < 65500) ? value : null); + position.set("rs485Fuel" + 5, (value < 65500) ? value : null); break; case 43: value = buf.readUnsignedShortLE(); - position.set("rs485fuel_level" + 6, (value < 65500) ? value : null); + position.set("rs485Fuel" + 6, (value < 65500) ? value : null); break; case 44: value = buf.readUnsignedShortLE(); - position.set("rs232fuel_level", (value < 65500) ? value : null); + position.set("rs232Fuel", (value < 65500) ? value : null); break; case 45: value = buf.readByte(); -- cgit v1.2.3 From c84ab2c13e5529c34e0acf48304618659b427985 Mon Sep 17 00:00:00 2001 From: Ed Freyfogle Date: Thu, 24 Mar 2022 11:28:14 +0100 Subject: support language param, if null defaults to "en" --- src/main/java/org/traccar/geocoder/OpenCageGeocoder.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java index 56161e52c..18cf3a715 100644 --- a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java +++ b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java @@ -21,16 +21,21 @@ import javax.json.JsonObject; public class OpenCageGeocoder extends JsonGeocoder { - private static String formatUrl(String url, String key) { + private static String formatUrl(String url, String key, String language) { if (url == null) { url = "https://api.opencagedata.com/geocode/v1"; } url += "/json?q=%f,%f&no_annotations=1&key=" + key; + if (language != null) { + url += "&language=" + language; + } else { + url += "&language=en"; + } return url; } - public OpenCageGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key), cacheSize, addressFormat); + public OpenCageGeocoder(String url, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(formatUrl(url, key, language), cacheSize, addressFormat); } @Override -- cgit v1.2.3 From be44289a93399b74a53797d992d994f7df6187d2 Mon Sep 17 00:00:00 2001 From: Ed Freyfogle Date: Thu, 24 Mar 2022 11:28:36 +0100 Subject: pass language to OpenCageGeocoder --- src/main/java/org/traccar/MainModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index d72e04588..842f7e3ce 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -181,7 +181,7 @@ public class MainModule extends AbstractModule { case "mapquest": return new MapQuestGeocoder(url, key, cacheSize, addressFormat); case "opencage": - return new OpenCageGeocoder(url, key, cacheSize, addressFormat); + return new OpenCageGeocoder(url, key, language, cacheSize, addressFormat); case "bingmaps": return new BingMapsGeocoder(url, key, cacheSize, addressFormat); case "factual": -- cgit v1.2.3 From eef38a4bf97a29873e29972b8f1fc7cdc4f9e927 Mon Sep 17 00:00:00 2001 From: Ed Freyfogle Date: Thu, 24 Mar 2022 11:30:08 +0100 Subject: change if logic to be same as url test --- src/main/java/org/traccar/geocoder/OpenCageGeocoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java index 18cf3a715..c4a82b03c 100644 --- a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java +++ b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java @@ -26,10 +26,10 @@ public class OpenCageGeocoder extends JsonGeocoder { url = "https://api.opencagedata.com/geocode/v1"; } url += "/json?q=%f,%f&no_annotations=1&key=" + key; - if (language != null) { - url += "&language=" + language; - } else { + if (language == null) { url += "&language=en"; + } else { + url += "&language=" + language; } return url; } -- cgit v1.2.3 From d65a3af95e2877b8f0fcb7f44cbfbd8b4f987622 Mon Sep 17 00:00:00 2001 From: Ed Freyfogle Date: Thu, 24 Mar 2022 11:32:25 +0100 Subject: pass language param to OpenCageGeocoder --- src/test/java/org/traccar/geocoder/GeocoderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/traccar/geocoder/GeocoderTest.java b/src/test/java/org/traccar/geocoder/GeocoderTest.java index 9134194f2..52dac625a 100644 --- a/src/test/java/org/traccar/geocoder/GeocoderTest.java +++ b/src/test/java/org/traccar/geocoder/GeocoderTest.java @@ -41,7 +41,7 @@ public class GeocoderTest { @Test public void testOpenCage() { Geocoder geocoder = new OpenCageGeocoder( - "http://api.opencagedata.com/geocode/v1", "SECRET", 0, new AddressFormat()); + "http://api.opencagedata.com/geocode/v1", "SECRET", "en", 0, new AddressFormat()); String address = geocoder.getAddress(34.116302, -118.051519, null); assertEquals("Charleston Road, California, US", address); } -- cgit v1.2.3 From f46a0471e9531febf33072adda9414e290354911 Mon Sep 17 00:00:00 2001 From: Ed Freyfogle Date: Thu, 24 Mar 2022 22:29:46 +0100 Subject: test with null instead of "en" --- src/test/java/org/traccar/geocoder/GeocoderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/traccar/geocoder/GeocoderTest.java b/src/test/java/org/traccar/geocoder/GeocoderTest.java index 52dac625a..91431fd6a 100644 --- a/src/test/java/org/traccar/geocoder/GeocoderTest.java +++ b/src/test/java/org/traccar/geocoder/GeocoderTest.java @@ -41,7 +41,7 @@ public class GeocoderTest { @Test public void testOpenCage() { Geocoder geocoder = new OpenCageGeocoder( - "http://api.opencagedata.com/geocode/v1", "SECRET", "en", 0, new AddressFormat()); + "http://api.opencagedata.com/geocode/v1", "SECRET", null, 0, new AddressFormat()); String address = geocoder.getAddress(34.116302, -118.051519, null); assertEquals("Charleston Road, California, US", address); } -- cgit v1.2.3 From 83af89dfe56753ab932014b89646c17577ba913d Mon Sep 17 00:00:00 2001 From: Ed Freyfogle Date: Thu, 24 Mar 2022 22:37:01 +0100 Subject: changed to be same as in Nominatim.java --- src/main/java/org/traccar/geocoder/OpenCageGeocoder.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java index c4a82b03c..bbcc00cd0 100644 --- a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java +++ b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java @@ -26,9 +26,7 @@ public class OpenCageGeocoder extends JsonGeocoder { url = "https://api.opencagedata.com/geocode/v1"; } url += "/json?q=%f,%f&no_annotations=1&key=" + key; - if (language == null) { - url += "&language=en"; - } else { + if (language != null) { url += "&language=" + language; } return url; -- cgit v1.2.3 From 56f7a4eab1b4ccc3801a24d7e2ede33d0ab9339c Mon Sep 17 00:00:00 2001 From: Yuriy Piskarev Date: Fri, 25 Mar 2022 11:12:32 +0300 Subject: - optimized parsing of similar protocol fields; --- .../protocol/NavtelecomProtocolDecoder.java | 62 +++------------------- 1 file changed, 6 insertions(+), 56 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index ff6f12dde..60f1091bb 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -193,7 +193,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - for (int j = 0; j < bits.length(); j++) { + for (int j = 0, l = 2; j < bits.length(); j++, l++) { if (bits.get(j)) { int value = 0; @@ -241,22 +241,12 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readShortLE() * 0.001); break; case 21: - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE() * 0.001); - break; case 22: - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE() * 0.001); - break; case 23: - position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShortLE() * 0.001); - break; case 24: - position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShortLE() * 0.001); - break; case 25: - position.set(Position.PREFIX_ADC + 5, buf.readUnsignedShortLE() * 0.001); - break; case 26: - position.set(Position.PREFIX_ADC + 6, buf.readUnsignedShortLE() * 0.001); + position.set(Position.PREFIX_ADC + (l - 21), buf.readUnsignedShortLE() * 0.001); break; case 29: value = buf.readUnsignedByte(); @@ -271,79 +261,39 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { } break; case 33: - position.set(Position.PREFIX_COUNT + 1, buf.readUnsignedIntLE()); - break; case 34: - position.set(Position.PREFIX_COUNT + 2, buf.readUnsignedIntLE()); + position.set(Position.PREFIX_COUNT + (l - 33), buf.readUnsignedIntLE()); break; case 35: - position.set("freq" + 1, buf.readUnsignedShortLE()); - break; case 36: - position.set("freq" + 2, buf.readUnsignedShortLE()); + position.set("freq" + (l - 35), buf.readUnsignedShortLE()); break; case 37: position.set("engine_hours", buf.readUnsignedIntLE()); break; case 38: - value = buf.readUnsignedShortLE(); - position.set("rs485Fuel" + 1, (value < 65500) ? value : null); - break; case 39: - value = buf.readUnsignedShortLE(); - position.set("rs485Fuel" + 2, (value < 65500) ? value : null); - break; case 40: - value = buf.readUnsignedShortLE(); - position.set("rs485Fuel" + 3, (value < 65500) ? value : null); - break; case 41: - value = buf.readUnsignedShortLE(); - position.set("rs485Fuel" + 4, (value < 65500) ? value : null); - break; case 42: - value = buf.readUnsignedShortLE(); - position.set("rs485Fuel" + 5, (value < 65500) ? value : null); - break; case 43: value = buf.readUnsignedShortLE(); - position.set("rs485Fuel" + 6, (value < 65500) ? value : null); + position.set("rs485Fuel" + (l - 38), (value < 65500) ? value : null); break; case 44: value = buf.readUnsignedShortLE(); position.set("rs232Fuel", (value < 65500) ? value : null); break; case 45: - value = buf.readByte(); - position.set(Position.PREFIX_TEMP + 1, (value != 0x80) ? value : null); - break; case 46: - value = buf.readByte(); - position.set(Position.PREFIX_TEMP + 2, (value != 0x80) ? value : null); - break; case 47: - value = buf.readByte(); - position.set(Position.PREFIX_TEMP + 3, (value != 0x80) ? value : null); - break; case 48: - value = buf.readByte(); - position.set(Position.PREFIX_TEMP + 4, (value != 0x80) ? value : null); - break; case 49: - value = buf.readByte(); - position.set(Position.PREFIX_TEMP + 5, (value != 0x80) ? value : null); - break; case 50: - value = buf.readByte(); - position.set(Position.PREFIX_TEMP + 6, (value != 0x80) ? value : null); - break; case 51: - value = buf.readByte(); - position.set(Position.PREFIX_TEMP + 7, (value != 0x80) ? value : null); - break; case 52: value = buf.readByte(); - position.set(Position.PREFIX_TEMP + 8, (value != 0x80) ? value : null); + position.set(Position.PREFIX_TEMP + (l - 45), (value != 0x80) ? value : null); break; default: buf.skipBytes(getItemLength(j + 1)); -- cgit v1.2.3 From 4350c1634b7cfd1e8005908b8c72ec32a882276f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 28 Mar 2022 09:54:04 -0700 Subject: Handle invalid operator --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 89ae48b3a..f83a49941 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -362,7 +362,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (cid != 0 && lac != 0) { CellTower cellTower = CellTower.fromLacCid(lac, cid); long operator = position.getInteger(Position.KEY_OPERATOR); - if (operator != 0) { + if (operator >= 1000) { cellTower.setOperator(operator); } position.setNetwork(new Network(cellTower)); diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 082d410c2..c3c32369c 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, binary( + "00000000000000da08030000017fcedf499600280431be0eded45d0038012d100000fa100901000200b300b4004501500415034702fa00054232a1180000cd3b2fce281d43001f02c700000006f10000a029000000017fcedea99600280432070eded3dd00380046130009000f0801010200b300b400450150051502470205423276180009cd3b2fce281d43001f02c700000027f10000a0290000000179d50853180027f65d3f0ed67212001500f1110061000f0801010200b300b4004501500515034702054234f4180061cd53d1ce28c043003e02c700000147f1000000290003000052cb")); + verifyPositions(decoder, binary( "00000000000000b98e0200000179555c7bf8010b3a1cfbebc142b00000000000000000ec000f000900f00000150000c80000450200710100740001070100fa0000ec01000500b500000018000000430d560044000000190000000100f1000000000000000000000179555c83c8010b3a1cfbebc142b0000000000000000185000f000900f00000150000c80000450200710100740001070100fa00018511000500b500000018000000430d560044000000190000000100f100000000000000000200003251")); -- cgit v1.2.3 From c14413c5bf0d2989109b4369fdb95a49f128c169 Mon Sep 17 00:00:00 2001 From: Yuriy Piskarev Date: Mon, 28 Mar 2022 20:12:57 +0300 Subject: - delete variable 'l'; --- .../java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 60f1091bb..df53d7c3d 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -193,7 +193,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - for (int j = 0, l = 2; j < bits.length(); j++, l++) { + for (int j = 0; j < bits.length(); j++) { if (bits.get(j)) { int value = 0; @@ -246,7 +246,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 24: case 25: case 26: - position.set(Position.PREFIX_ADC + (l - 21), buf.readUnsignedShortLE() * 0.001); + position.set(Position.PREFIX_ADC + (j + 2 - 21), buf.readUnsignedShortLE() * 0.001); break; case 29: value = buf.readUnsignedByte(); @@ -262,11 +262,11 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { break; case 33: case 34: - position.set(Position.PREFIX_COUNT + (l - 33), buf.readUnsignedIntLE()); + position.set(Position.PREFIX_COUNT + (j + 2 - 33), buf.readUnsignedIntLE()); break; case 35: case 36: - position.set("freq" + (l - 35), buf.readUnsignedShortLE()); + position.set("freq" + (j + 2 - 35), buf.readUnsignedShortLE()); break; case 37: position.set("engine_hours", buf.readUnsignedIntLE()); @@ -278,7 +278,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 42: case 43: value = buf.readUnsignedShortLE(); - position.set("rs485Fuel" + (l - 38), (value < 65500) ? value : null); + position.set("rs485Fuel" + (j + 2 - 38), (value < 65500) ? value : null); break; case 44: value = buf.readUnsignedShortLE(); @@ -293,7 +293,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 51: case 52: value = buf.readByte(); - position.set(Position.PREFIX_TEMP + (l - 45), (value != 0x80) ? value : null); + position.set(Position.PREFIX_TEMP + (j + 2 - 45), (value != 0x80) ? value : null); break; default: buf.skipBytes(getItemLength(j + 1)); -- cgit v1.2.3 From 3a4757af42f4a7382b1b70cf4768023152238b32 Mon Sep 17 00:00:00 2001 From: Yuriy Piskarev Date: Mon, 28 Mar 2022 21:21:21 +0300 Subject: - replacing expression with BitUtil; --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index df53d7c3d..37729236e 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -211,7 +211,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 8: value = buf.readUnsignedByte(); position.setValid(BitUtil.check(value, 1)); - position.set(Position.KEY_SATELLITES, ((value & 0b11111100) >> 2)); + position.set(Position.KEY_SATELLITES, BitUtil.from(value, 2)); break; case 9: position.setFixTime(new Date(buf.readUnsignedIntLE() * 1000)); -- cgit v1.2.3 From c4f36004c11306130f17be2f271d8e95ddf87ffc Mon Sep 17 00:00:00 2001 From: Yuriy Piskarev Date: Mon, 28 Mar 2022 22:00:23 +0300 Subject: - use key KEY_HOURS; --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 37729236e..7d6991a2f 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -269,7 +269,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { position.set("freq" + (j + 2 - 35), buf.readUnsignedShortLE()); break; case 37: - position.set("engine_hours", buf.readUnsignedIntLE()); + position.set(Position.KEY_HOURS, buf.readUnsignedIntLE()); break; case 38: case 39: -- cgit v1.2.3 From b98bf59312c136aa4324e9e7bdbef0086067e5e7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 31 Mar 2022 09:11:17 -0700 Subject: Fix Navtelecom digital IO --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 7d6991a2f..5fb3e771f 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -251,13 +251,13 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 29: value = buf.readUnsignedByte(); for (int k = 0; k <= 7; k++) { - position.set(Position.PREFIX_IN + (k + 1), BitUtil.check(value, k) ? 1 : 0); + position.set(Position.PREFIX_IN + (k + 1), BitUtil.check(value, k)); } break; case 31: value = buf.readUnsignedByte(); for (int k = 0; k <= 3; k++) { - position.set(Position.PREFIX_OUT + (k + 1), BitUtil.check(value, k) ? 1 : 0); + position.set(Position.PREFIX_OUT + (k + 1), BitUtil.check(value, k)); } break; case 33: -- cgit v1.2.3 From 307c4dd690c5826e076657fa83f2ddd41cec1126 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 31 Mar 2022 19:35:46 -0700 Subject: Decode JT701 RFID value --- .../org/traccar/protocol/Jt600ProtocolDecoder.java | 60 ++++++++++++++++++++++ .../traccar/protocol/Jt600ProtocolDecoderTest.java | 3 ++ 2 files changed, 63 insertions(+) diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index dc4bd3486..b4b70091b 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -374,6 +374,64 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { return position; } + private static final Pattern PATTERN_P45 = new PatternBuilder() + .text("(") + .number("(d+),") // id + .text("P45,") // type + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(d+.d+),([NS]),") // latitude + .number("(d+.d+),([EW]),") // longitude + .expression("([AV]),") // validity + .number("(d+),") // speed + .number("(d+),") // course + .number("d+,") // event source + .number("d+,") // unlock verification + .number("(d+),") // rfid + .number("d+,") // password verification + .number("d+,") // incorrect password count + .number("(d+),") // index + .any() + .compile(); + + private Position decodeP45(String sentence, Channel channel, SocketAddress remoteAddress) { + + Parser parser = new Parser(PATTERN_P45, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setValid(parser.next().equals("A")); + + position.setSpeed(UnitsConverter.knotsFromMph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + + String rfid = parser.next(); + if (!rfid.equals("0000000000")) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid); + } + + int index = parser.nextInt(); + + if (channel != null) { + channel.writeAndFlush(new NetworkMessage("(P69,0," + index + ")", remoteAddress)); + } + + return position; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -387,6 +445,8 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { String sentence = buf.toString(StandardCharsets.US_ASCII); if (sentence.contains("W01")) { return decodeW01(sentence, channel, remoteAddress); + } else if (sentence.contains("P45")) { + return decodeP45(sentence, channel, remoteAddress); } else { return decodeU01(sentence, channel, remoteAddress); } diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 3c681ec58..3bf01c1ae 100644 --- a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { var decoder = new Jt600ProtocolDecoder(null); + verifyPosition(decoder, buffer( + "(8000632862,P45,290322,132412,25.28217,S,57.54683,W,A,0,0,5,0,0000000000,0,0,9,0)")); + verifyPositions(decoder, binary( "2480413009781914003406102107544354193631006213423b00000000006c070000000020e064f91ea0671d00020f0f0f0f0f0f0f0f0f0f07f100ea0f6e")); -- cgit v1.2.3 From 9ec2d09ad8a757d58f70812b9cf5e835321382e6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Feb 2022 17:33:58 -0800 Subject: Migrate permissions to storage --- debug.xml | 1 + gradle/checkstyle.xml | 4 +- src/main/java/org/traccar/MainModule.java | 5 - .../java/org/traccar/api/BaseObjectResource.java | 105 ++++------------ src/main/java/org/traccar/api/BaseResource.java | 12 +- .../org/traccar/api/ExtendedObjectResource.java | 51 ++++---- src/main/java/org/traccar/api/MediaFilter.java | 6 +- .../java/org/traccar/api/SimpleObjectResource.java | 30 +++-- .../org/traccar/api/resource/DeviceResource.java | 4 +- .../org/traccar/api/resource/EventResource.java | 18 +-- .../traccar/api/resource/NotificationResource.java | 3 +- .../org/traccar/api/resource/PositionResource.java | 2 +- .../org/traccar/api/resource/ReportResource.java | 20 +-- .../traccar/api/security/PermissionsService.java | 136 +++++++++++++++++++++ src/main/java/org/traccar/config/Keys.java | 7 ++ .../java/org/traccar/database/DeviceManager.java | 3 +- .../org/traccar/database/PermissionsManager.java | 22 ---- src/main/java/org/traccar/model/Permission.java | 2 +- src/main/java/org/traccar/model/User.java | 6 + .../java/org/traccar/storage/DatabaseStorage.java | 57 +++++++-- .../java/org/traccar/storage/MemoryStorage.java | 5 +- .../java/org/traccar/storage/QueryBuilder.java | 20 +-- src/main/java/org/traccar/storage/Storage.java | 17 ++- .../java/org/traccar/storage/query/Condition.java | 38 ++++++ 24 files changed, 375 insertions(+), 199 deletions(-) create mode 100644 src/main/java/org/traccar/api/security/PermissionsService.java diff --git a/debug.xml b/debug.xml index f9515bb2b..941b849bb 100644 --- a/debug.xml +++ b/debug.xml @@ -11,6 +11,7 @@ true true + true org.h2.Driver jdbc:h2:./target/database diff --git a/gradle/checkstyle.xml b/gradle/checkstyle.xml index 9d30e53d6..6cff6ffa5 100644 --- a/gradle/checkstyle.xml +++ b/gradle/checkstyle.xml @@ -122,7 +122,9 @@ - + + + diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 842f7e3ce..79cfcc0a8 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -444,9 +444,4 @@ public class MainModule extends AbstractModule { return GlobalTimer.getTimer(); } - @Override - protected void configure() { - binder().requireExplicitBindings(); - } - } diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 22756f62a..07c74449c 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,70 +16,44 @@ */ package org.traccar.api; -import java.sql.SQLException; -import java.util.Set; - -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.Response; - import org.traccar.Context; import org.traccar.database.BaseObjectManager; import org.traccar.database.ExtendedObjectManager; -import org.traccar.database.ManagableObjects; import org.traccar.database.SimpleObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; -import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.model.GroupedModel; -import org.traccar.model.ScheduledModel; +import org.traccar.model.Permission; import org.traccar.model.User; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Response; public abstract class BaseObjectResource extends BaseResource { - private final Class baseClass; + protected final Class baseClass; public BaseObjectResource(Class baseClass) { this.baseClass = baseClass; } - protected final Class getBaseClass() { - return baseClass; - } - - protected final Set getSimpleManagerItems(BaseObjectManager manager, boolean all, long userId) { - Set result; - if (all) { - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - result = manager.getAllItems(); - } else { - Context.getPermissionsManager().checkManager(getUserId()); - result = ((ManagableObjects) manager).getManagedItems(getUserId()); - } - } else { - if (userId == 0) { - userId = getUserId(); - } - Context.getPermissionsManager().checkUser(getUserId(), userId); - result = ((ManagableObjects) manager).getUserItems(userId); - } - return result; - } - @Path("{id}") @GET - public Response getSingle(@PathParam("id") long id) throws SQLException { - Context.getPermissionsManager().checkPermission(baseClass, getUserId(), id); - BaseObjectManager manager = Context.getManager(baseClass); - T entity = manager.getById(id); + public Response getSingle(@PathParam("id") long id) throws StorageException { + permissionsService.checkPermission(baseClass, getUserId(), id); + T entity = storage.getObject(baseClass, new Request( + new Columns.All(), new Condition.Equals("id", "id", id))); if (entity != null) { return Response.ok(entity).build(); } else { @@ -89,25 +63,13 @@ public abstract class BaseObjectResource extends BaseResour @POST public Response add(T entity) throws StorageException { - Context.getPermissionsManager().checkReadonly(getUserId()); - if (baseClass.equals(Device.class)) { - Context.getPermissionsManager().checkDeviceReadonly(getUserId()); - Context.getPermissionsManager().checkDeviceLimit(getUserId()); - } else if (baseClass.equals(Command.class)) { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } else if (entity instanceof GroupedModel && ((GroupedModel) entity).getGroupId() != 0) { - Context.getPermissionsManager().checkPermission( - Group.class, getUserId(), ((GroupedModel) entity).getGroupId()); - } else if (entity instanceof ScheduledModel && ((ScheduledModel) entity).getCalendarId() != 0) { - Context.getPermissionsManager().checkPermission( - Calendar.class, getUserId(), ((ScheduledModel) entity).getCalendarId()); - } + permissionsService.checkEdit(getUserId(), entity, true); BaseObjectManager manager = Context.getManager(baseClass); manager.addItem(entity); LogAction.create(getUserId(), entity); - Context.getDataManager().linkObject(User.class, getUserId(), baseClass, entity.getId(), true); + storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); if (manager instanceof SimpleObjectManager) { @@ -122,22 +84,8 @@ public abstract class BaseObjectResource extends BaseResour @Path("{id}") @PUT public Response update(T entity) throws StorageException { - Context.getPermissionsManager().checkReadonly(getUserId()); - if (baseClass.equals(Device.class)) { - Context.getPermissionsManager().checkDeviceReadonly(getUserId()); - } else if (baseClass.equals(User.class)) { - User before = Context.getPermissionsManager().getUser(entity.getId()); - Context.getPermissionsManager().checkUserUpdate(getUserId(), before, (User) entity); - } else if (baseClass.equals(Command.class)) { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } else if (entity instanceof GroupedModel && ((GroupedModel) entity).getGroupId() != 0) { - Context.getPermissionsManager().checkPermission( - Group.class, getUserId(), ((GroupedModel) entity).getGroupId()); - } else if (entity instanceof ScheduledModel && ((ScheduledModel) entity).getCalendarId() != 0) { - Context.getPermissionsManager().checkPermission( - Calendar.class, getUserId(), ((ScheduledModel) entity).getCalendarId()); - } - Context.getPermissionsManager().checkPermission(baseClass, getUserId(), entity.getId()); + permissionsService.checkEdit(getUserId(), entity, false); + permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); Context.getManager(baseClass).updateItem(entity); LogAction.edit(getUserId(), entity); @@ -152,13 +100,8 @@ public abstract class BaseObjectResource extends BaseResour @Path("{id}") @DELETE public Response remove(@PathParam("id") long id) throws StorageException { - Context.getPermissionsManager().checkReadonly(getUserId()); - if (baseClass.equals(Device.class)) { - Context.getPermissionsManager().checkDeviceReadonly(getUserId()); - } else if (baseClass.equals(Command.class)) { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } - Context.getPermissionsManager().checkPermission(baseClass, getUserId(), id); + permissionsService.checkEdit(getUserId(), baseClass, false); + permissionsService.checkPermission(baseClass, getUserId(), id); BaseObjectManager manager = Context.getManager(baseClass); manager.removeItem(id); diff --git a/src/main/java/org/traccar/api/BaseResource.java b/src/main/java/org/traccar/api/BaseResource.java index 6dff8c8c3..33abe73fa 100644 --- a/src/main/java/org/traccar/api/BaseResource.java +++ b/src/main/java/org/traccar/api/BaseResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,11 @@ */ package org.traccar.api; +import org.traccar.api.security.PermissionsService; import org.traccar.api.security.UserPrincipal; +import org.traccar.storage.Storage; +import javax.inject.Inject; import javax.ws.rs.core.Context; import javax.ws.rs.core.SecurityContext; @@ -25,6 +28,12 @@ public class BaseResource { @Context private SecurityContext securityContext; + @Inject + protected Storage storage; + + @Inject + protected PermissionsService permissionsService; + protected long getUserId() { UserPrincipal principal = (UserPrincipal) securityContext.getUserPrincipal(); if (principal != null) { @@ -32,4 +41,5 @@ public class BaseResource { } return 0; } + } diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 9e554217e..a12314a2c 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,17 +16,19 @@ */ package org.traccar.api; -import java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; +import org.traccar.model.BaseModel; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.ws.rs.GET; import javax.ws.rs.QueryParam; - -import org.traccar.Context; -import org.traccar.database.ExtendedObjectManager; -import org.traccar.model.BaseModel; +import java.util.Collection; +import java.util.LinkedList; public class ExtendedObjectResource extends BaseObjectResource { @@ -36,27 +38,28 @@ public class ExtendedObjectResource extends BaseObjectResou @GET public Collection get( - @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("groupId") long groupId, - @QueryParam("deviceId") long deviceId, @QueryParam("refresh") boolean refresh) throws SQLException { - - ExtendedObjectManager manager = (ExtendedObjectManager) Context.getManager(getBaseClass()); - if (refresh) { - manager.refreshItems(); - } + @QueryParam("all") boolean all, @QueryParam("userId") long userId, + @QueryParam("groupId") long groupId, @QueryParam("deviceId") long deviceId) throws StorageException { - Set result = new HashSet<>(getSimpleManagerItems(manager, all, userId)); + var conditions = new LinkedList(); - if (groupId != 0) { - Context.getPermissionsManager().checkGroup(getUserId(), groupId); - result.retainAll(manager.getGroupItems(groupId)); + if (all) { + permissionsService.checkAdmin(getUserId()); + } else { + permissionsService.checkUser(getUserId(), userId); + conditions.add(new Condition.Permission(User.class, userId, baseClass)); } - if (deviceId != 0) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - result.retainAll(manager.getDeviceItems(deviceId)); + if (groupId > 0) { + permissionsService.checkPermission(Group.class, getUserId(), groupId); + conditions.add(new Condition.Permission(Group.class, groupId, baseClass)); + } + if (deviceId > 0) { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + conditions.add(new Condition.Permission(Device.class, deviceId, baseClass)); } - return manager.getItems(result); + return storage.getObjects(baseClass, new Request(new Columns.All(), Condition.merge(conditions))); } } diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index 77731a810..0433147f8 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,7 +17,6 @@ package org.traccar.api; import java.io.IOException; -import java.sql.SQLException; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -76,9 +75,6 @@ public class MediaFilter implements Filter { } catch (SecurityException e) { httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); httpResponse.getWriter().println(Log.exceptionStack(e)); - } catch (SQLException e) { - httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); - httpResponse.getWriter().println(Log.exceptionStack(e)); } } diff --git a/src/main/java/org/traccar/api/SimpleObjectResource.java b/src/main/java/org/traccar/api/SimpleObjectResource.java index a7fcae0e7..b55bf91e3 100644 --- a/src/main/java/org/traccar/api/SimpleObjectResource.java +++ b/src/main/java/org/traccar/api/SimpleObjectResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,15 +16,17 @@ */ package org.traccar.api; -import java.sql.SQLException; -import java.util.Collection; +import org.traccar.model.BaseModel; +import org.traccar.model.User; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.ws.rs.GET; import javax.ws.rs.QueryParam; - -import org.traccar.Context; -import org.traccar.database.BaseObjectManager; -import org.traccar.model.BaseModel; +import java.util.Collection; +import java.util.LinkedList; public class SimpleObjectResource extends BaseObjectResource { @@ -34,10 +36,18 @@ public class SimpleObjectResource extends BaseObjectResourc @GET public Collection get( - @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException { + @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws StorageException { + + var conditions = new LinkedList(); + + if (all) { + permissionsService.checkAdmin(getUserId()); + } else { + permissionsService.checkUser(getUserId(), userId); + conditions.add(new Condition.Permission(User.class, userId, baseClass)); + } - BaseObjectManager manager = Context.getManager(getBaseClass()); - return manager.getItems(getSimpleManagerItems(manager, all, userId)); + return storage.getObjects(baseClass, new Request(new Columns.All(), Condition.merge(conditions))); } } diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 9436b59f6..309308e75 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -31,8 +31,6 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; - -import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -51,7 +49,7 @@ public class DeviceResource extends BaseObjectResource { public Collection get( @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("uniqueId") List uniqueIds, - @QueryParam("id") List deviceIds) throws SQLException { + @QueryParam("id") List deviceIds) { DeviceManager deviceManager = Context.getDeviceManager(); Set result; if (all) { diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index 354d96e4f..38b101b25 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -15,6 +15,11 @@ */ package org.traccar.api.resource; +import org.traccar.Context; +import org.traccar.api.BaseResource; +import org.traccar.model.Event; +import org.traccar.storage.StorageException; + import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -24,13 +29,6 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.model.Event; -import org.traccar.model.Geofence; -import org.traccar.model.Maintenance; -import org.traccar.storage.StorageException; - @Path("events") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -44,12 +42,6 @@ public class EventResource extends BaseResource { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } Context.getPermissionsManager().checkDevice(getUserId(), event.getDeviceId()); - if (event.getGeofenceId() != 0) { - Context.getPermissionsManager().checkPermission(Geofence.class, getUserId(), event.getGeofenceId()); - } - if (event.getMaintenanceId() != 0) { - Context.getPermissionsManager().checkPermission(Maintenance.class, getUserId(), event.getMaintenanceId()); - } return event; } diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index 9631a52b7..cf4b66fa1 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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,6 @@ import org.traccar.model.Notification; import org.traccar.model.Typed; import org.traccar.notification.MessageException; - @Path("notifications") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 511032402..941417231 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -55,7 +55,7 @@ public class PositionResource extends BaseResource { } else { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); if (from != null && to != null) { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return Context.getDataManager().getPositions(deviceId, from, to); } else { return Collections.singleton(Context.getDeviceManager().getLastPosition(deviceId)); diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 03df0d03a..901385d0d 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -99,7 +99,7 @@ public class ReportResource extends BaseResource { public Collection getRoute( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); return Route.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -111,7 +111,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); Route.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); @@ -124,7 +124,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); return Events.getObjects(getUserId(), deviceIds, groupIds, types, from, to); } @@ -137,7 +137,7 @@ public class ReportResource extends BaseResource { @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); Events.getExcel(stream, getUserId(), deviceIds, groupIds, types, from, to); @@ -150,7 +150,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily) throws StorageException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); return Summary.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); } @@ -163,7 +163,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily, @QueryParam("mail") boolean mail) throws StorageException, IOException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); Summary.getExcel(stream, getUserId(), deviceIds, groupIds, from, to, daily); @@ -176,7 +176,7 @@ public class ReportResource extends BaseResource { public Collection getTrips( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); return Trips.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -188,7 +188,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); Trips.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); @@ -201,7 +201,7 @@ public class ReportResource extends BaseResource { public Collection getStops( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); return Stops.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -213,7 +213,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - Context.getPermissionsManager().checkDisableReports(getUserId()); + permissionsService.checkReports(getUserId()); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); Stops.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java new file mode 100644 index 000000000..e39b8808f --- /dev/null +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -0,0 +1,136 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.api.security; + +import org.traccar.model.Calendar; +import org.traccar.model.Command; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.model.GroupedModel; +import org.traccar.model.ScheduledModel; +import org.traccar.model.Server; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; + +public class PermissionsService { + + private final Storage storage; + + private Server server; + private User user; + + @Inject + public PermissionsService(Storage storage) { + this.storage = storage; + } + + private Server getServer() throws StorageException { + if (server == null) { + server = storage.getObject( + Server.class, new Request(new Columns.All())); + } + return server; + } + + private User getUser(long userId) throws StorageException { + if (user == null) { + user = storage.getObject( + User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); + } + return user; + } + + public void checkAdmin(long userId) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator()) { + throw new SecurityException("Account is readonly"); + } + } + + public void checkReports(long userId) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator() + && (server.getDisableReports() || getUser(userId).getDisableReports())) { + throw new SecurityException("Reports are disabled"); + } + } + + public void checkEdit(long userId, Class clazz, boolean addition) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator()) { + boolean denied = false; + if (getServer().getReadonly() || getUser(userId).getReadonly()) { + denied = true; + } else if (clazz.equals(Device.class)) { + denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly(); + if (addition) { + int deviceCount = storage.getPermissions(User.class, userId, Device.class).size(); + denied = deviceCount >= getUser(userId).getDeviceLimit(); + } + } else if (clazz.equals(Command.class)) { + denied = getServer().getLimitCommands() || getUser(userId).getLimitCommands(); + } + if (denied) { + throw new SecurityException("Write access denied"); + } + } + } + + public void checkEdit(long userId, Object object, boolean addition) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator()) { + checkEdit(userId, object.getClass(), addition); + boolean denied = false; + if (object instanceof GroupedModel) { + long groupId = ((GroupedModel) object).getGroupId(); + if (groupId > 0) { + denied = storage.getPermissions(User.class, userId, Group.class, groupId).isEmpty(); + // TODO TEST NESTED GROUP PERMISSION + } + } + if (object instanceof ScheduledModel) { + long calendarId = ((ScheduledModel) object).getCalendarId(); + if (calendarId > 0) { + denied = storage.getPermissions(User.class, userId, Calendar.class, calendarId).isEmpty(); + } + } + if (denied) { + throw new SecurityException("Write access denied"); + } + } + } + + public void checkUser(long userId, long managedUserId) throws StorageException, SecurityException { + if (userId != managedUserId && !getUser(userId).getAdministrator()) { + if (!getUser(userId).getManager() + || storage.getPermissions(User.class, userId, User.class, managedUserId).isEmpty()) { + throw new SecurityException("User access denied"); + } + } + } + + public void checkPermission( + Class clazz, long userId, long objectId) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator() + && storage.getPermissions(User.class, userId, clazz, objectId).isEmpty()) { + // TODO handle nested objects + throw new SecurityException(clazz.getSimpleName() + " access denied"); + } + } + +} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index ccfe4bee7..1341f4143 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1271,6 +1271,13 @@ public final class Keys { "logger.console", Collections.singletonList(KeyType.GLOBAL)); + /** + * Log executed SQL queries. + */ + public static final ConfigKey LOGGER_QUERIES = new ConfigKey<>( + "logger.queries", + Collections.singletonList(KeyType.GLOBAL)); + /** * Log file name. For rotating logs, a date is added at the end of the file name for non-current logs. */ diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 40591e869..a9b8454eb 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -15,7 +15,6 @@ */ package org.traccar.database; -import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; @@ -110,7 +109,7 @@ public class DeviceManager extends BaseObjectManager implements Identity } @Override - public Device getByUniqueId(String uniqueId) throws SQLException { + public Device getByUniqueId(String uniqueId) { boolean forceUpdate; try { readLock(); diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 2bb808033..9a673c784 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -264,45 +264,23 @@ public class PermissionsManager { return user != null && user.getReadonly(); } - public boolean getUserDeviceReadonly(long userId) { - User user = getUser(userId); - return user != null && user.getDeviceReadonly(); - } - public boolean getUserLimitCommands(long userId) { User user = getUser(userId); return user != null && user.getLimitCommands(); } - public boolean getUserDisableReport(long userId) { - User user = getUser(userId); - return user != null && user.getDisableReports(); - } - public void checkReadonly(long userId) throws SecurityException { if (!getUserAdmin(userId) && (server.getReadonly() || getUserReadonly(userId))) { throw new SecurityException("Account is readonly"); } } - public void checkDeviceReadonly(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getDeviceReadonly() || getUserDeviceReadonly(userId))) { - throw new SecurityException("Account is device readonly"); - } - } - public void checkLimitCommands(long userId) throws SecurityException { if (!getUserAdmin(userId) && (server.getLimitCommands() || getUserLimitCommands(userId))) { throw new SecurityException("Account has limit sending commands"); } } - public void checkDisableReports(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getDisableReports() || getUserDisableReport(userId))) { - throw new SecurityException("Account has reports disabled"); - } - } - public void checkUserDeviceCommand(long userId, long deviceId, long commandId) throws SecurityException { if (!getUserAdmin(userId) && Context.getCommandsManager().checkDeviceCommand(deviceId, commandId)) { throw new SecurityException("Command can not be sent to this device"); diff --git a/src/main/java/org/traccar/model/Permission.java b/src/main/java/org/traccar/model/Permission.java index ad0176b39..bace6b7d4 100644 --- a/src/main/java/org/traccar/model/Permission.java +++ b/src/main/java/org/traccar/model/Permission.java @@ -71,7 +71,7 @@ public class Permission { data.put(getKey(propertyClass), propertyId); } - private static String getKey(Class clazz) { + public static String getKey(Class clazz) { return Introspector.decapitalize(clazz.getSimpleName()) + "Id"; } diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 464d0cbfe..6a67f3276 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -79,6 +79,12 @@ public class User extends ExtendedModel { private boolean administrator; + @QueryIgnore + @JsonIgnore + public boolean getManager() { + return userLimit != 0; + } + public boolean getAdministrator() { return administrator; } diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index d73dc7b25..4c985d98a 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage; import org.traccar.model.Permission; @@ -10,6 +25,7 @@ import org.traccar.storage.query.Request; import javax.sql.DataSource; import java.sql.SQLException; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -96,9 +112,20 @@ public class DatabaseStorage extends Storage { } @Override - public List getPermissions(Class ownerClass, Class propertyClass) throws StorageException { + public List getPermissions( + Class ownerClass, long ownerId, Class propertyClass, long propertyId) throws StorageException { StringBuilder query = new StringBuilder("SELECT * FROM "); query.append(Permission.getStorageName(ownerClass, propertyClass)); + var conditions = new LinkedList(); + if (ownerId > 0) { + conditions.add(new Condition.Equals( + Permission.getKey(ownerClass), Permission.getKey(ownerClass), ownerId)); + } + if (propertyId > 0) { + conditions.add(new Condition.Equals( + Permission.getKey(propertyClass), Permission.getKey(propertyClass), propertyId)); + } + query.append(formatCondition(Condition.merge(conditions))); try { QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); return builder.executePermissionsQuery(); @@ -154,18 +181,21 @@ public class DatabaseStorage extends Storage { private Map getConditionVariables(Condition genericCondition) { Map results = new HashMap<>(); if (genericCondition instanceof Condition.Compare) { - Condition.Compare condition = (Condition.Compare) genericCondition; + var condition = (Condition.Compare) genericCondition; if (condition.getValue() != null) { results.put(condition.getVariable(), condition.getValue()); } } else if (genericCondition instanceof Condition.Between) { - Condition.Between condition = (Condition.Between) genericCondition; + var condition = (Condition.Between) genericCondition; results.put(condition.getFromVariable(), condition.getFromValue()); results.put(condition.getToVariable(), condition.getToValue()); } else if (genericCondition instanceof Condition.Binary) { - Condition.Binary condition = (Condition.Binary) genericCondition; + var condition = (Condition.Binary) genericCondition; results.putAll(getConditionVariables(condition.getFirst())); results.putAll(getConditionVariables(condition.getSecond())); + } else if (genericCondition instanceof Condition.Permission) { + var condition = (Condition.Permission) genericCondition; + results.put(Permission.getKey(condition.getOwnerClass()), condition.getOwnerId()); } return results; } @@ -187,7 +217,7 @@ public class DatabaseStorage extends Storage { } if (genericCondition instanceof Condition.Compare) { - Condition.Compare condition = (Condition.Compare) genericCondition; + var condition = (Condition.Compare) genericCondition; result.append(condition.getColumn()); result.append(" "); result.append(condition.getOperator()); @@ -196,7 +226,7 @@ public class DatabaseStorage extends Storage { } else if (genericCondition instanceof Condition.Between) { - Condition.Between condition = (Condition.Between) genericCondition; + var condition = (Condition.Between) genericCondition; result.append(condition.getColumn()); result.append(" BETWEEN :"); result.append(condition.getFromVariable()); @@ -205,13 +235,26 @@ public class DatabaseStorage extends Storage { } else if (genericCondition instanceof Condition.Binary) { - Condition.Binary condition = (Condition.Binary) genericCondition; + var condition = (Condition.Binary) genericCondition; result.append(formatCondition(condition.getFirst(), false)); result.append(" "); result.append(condition.getOperator()); result.append(" "); result.append(formatCondition(condition.getSecond(), false)); + } else if (genericCondition instanceof Condition.Permission) { + + var condition = (Condition.Permission) genericCondition; + result.append("id IN (SELECT "); + result.append(Permission.getKey(condition.getPropertyClass())); + result.append(" FROM "); + result.append(Permission.getStorageName(condition.getOwnerClass(), condition.getPropertyClass())); + result.append(" WHERE "); + result.append(Permission.getKey(condition.getOwnerClass())); + result.append(" = :"); + result.append(Permission.getKey(condition.getOwnerClass())); + result.append(")"); + } } return result.toString(); diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java index 9cfe30a2b..115bbea7a 100644 --- a/src/main/java/org/traccar/storage/MemoryStorage.java +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -38,8 +38,11 @@ public class MemoryStorage extends Storage { } @Override - public List getPermissions(Class ownerClass, Class propertyClass) { + public List getPermissions( + Class ownerClass, long ownerId, Class propertyClass, long propertyId) { return getPermissionsSet(ownerClass, propertyClass).stream() + .filter(pair -> ownerId == 0 || pair.getFirst().equals(ownerId)) + .filter(pair -> propertyId == 0 || pair.getSecond().equals(propertyId)) .map(pair -> new Permission(ownerClass, pair.getFirst(), propertyClass, pair.getSecond())) .collect(Collectors.toList()); } diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index da8002f0b..874a046b4 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.config.Keys; import org.traccar.model.Permission; import javax.sql.DataSource; @@ -309,15 +310,6 @@ public final class QueryBuilder { void process(T object, ResultSet resultSet) throws SQLException; } - public T executeQuerySingle(Class clazz) throws SQLException { - List result = executeQuery(clazz); - if (!result.isEmpty()) { - return result.iterator().next(); - } else { - return null; - } - } - private void addProcessors( List> processors, final Class parameterType, final Method method, final String name) { @@ -395,6 +387,12 @@ public final class QueryBuilder { } } + private void logQuery() { + if (Context.getConfig().getBoolean(Keys.LOGGER_QUERIES)) { + LOGGER.info(query); + } + } + public List executeQuery(Class clazz) throws SQLException { List result = new LinkedList<>(); @@ -402,6 +400,8 @@ public final class QueryBuilder { try { + logQuery(); + try (ResultSet resultSet = statement.executeQuery()) { ResultSetMetaData resultMetaData = resultSet.getMetaData(); @@ -457,6 +457,7 @@ public final class QueryBuilder { if (query != null) { try { + logQuery(); statement.execute(); if (returnGeneratedKeys) { ResultSet resultSet = statement.getGeneratedKeys(); @@ -476,6 +477,7 @@ public final class QueryBuilder { List result = new LinkedList<>(); if (query != null) { try { + logQuery(); try (ResultSet resultSet = statement.executeQuery()) { ResultSetMetaData resultMetaData = resultSet.getMetaData(); while (resultSet.next()) { diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java index 22c48cae0..3b27f57e9 100644 --- a/src/main/java/org/traccar/storage/Storage.java +++ b/src/main/java/org/traccar/storage/Storage.java @@ -16,12 +16,27 @@ public abstract class Storage { public abstract void removeObject(Class clazz, Request request) throws StorageException; public abstract List getPermissions( - Class ownerClass, Class propertyClass) throws StorageException; + Class ownerClass, long ownerId, Class propertyClass, long propertyId) throws StorageException; public abstract void addPermission(Permission permission) throws StorageException; public abstract void removePermission(Permission permission) throws StorageException; + public List getPermissions( + Class ownerClass, Class propertyClass) throws StorageException { + return getPermissions(ownerClass, 0, propertyClass, 0); + } + + public List getPermissions( + Class ownerClass, long ownerId, Class propertyClass) throws StorageException { + return getPermissions(ownerClass, ownerId, propertyClass, 0); + } + + public List getPermissions( + Class ownerClass, Class propertyClass, long propertyId) throws StorageException { + return getPermissions(ownerClass, 0, propertyClass, propertyId); + } + public T getObject(Class clazz, Request request) throws StorageException { var objects = getObjects(clazz, request); return objects.isEmpty() ? null : objects.get(0); diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 82c8e8479..304440698 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -1,7 +1,21 @@ package org.traccar.storage.query; +import java.util.List; + public interface Condition { + static Condition merge(List conditions) { + Condition result = null; + var iterator = conditions.iterator(); + if (iterator.hasNext()) { + result = iterator.next(); + while (iterator.hasNext()) { + result = new Condition.And(result, iterator.next()); + } + } + return result; + } + class Equals extends Compare { public Equals(String column, String variable) { this(column, variable, null); @@ -114,4 +128,28 @@ public interface Condition { } } + class Permission implements Condition { + private final Class ownerClass; + private final long ownerId; + private final Class propertyClass; + + public Permission(Class ownerClass, long ownerId, Class propertyClass) { + this.ownerClass = ownerClass; + this.ownerId = ownerId; + this.propertyClass = propertyClass; + } + + public Class getOwnerClass() { + return ownerClass; + } + + public long getOwnerId() { + return ownerId; + } + + public Class getPropertyClass() { + return propertyClass; + } + } + } -- cgit v1.2.3 From e80f2ce8b6d1a9aba9277168b0b365d610c31f8e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 6 Apr 2022 09:20:00 -0700 Subject: Update API documentation --- swagger.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swagger.json b/swagger.json index 9882c92d7..ac0d73d5b 100644 --- a/swagger.json +++ b/swagger.json @@ -2891,6 +2891,10 @@ "type": "integer", "description": "Geofence Id, can be second parameter only" }, + "notificationId": { + "type": "integer", + "description": "Notification Id, can be second parameter only" + }, "calendarId": { "type": "integer", "description": "Calendar Id, can be second parameter only and only in combination with userId" -- cgit v1.2.3 From 8f90707e17e66e9d1aa98fa5fd06cdd30e9c2760 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 6 Apr 2022 18:17:52 -0700 Subject: Migrate attribute resource --- .../traccar/api/resource/AttributeResource.java | 68 +++++++++++++--------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index d2dc28903..478b7acfd 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,9 +30,13 @@ import javax.ws.rs.core.Response; import org.traccar.Context; import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Attribute; +import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.handler.ComputedAttributesHandler; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; @Path("attributes/computed") @Produces(MediaType.APPLICATION_JSON) @@ -45,51 +49,61 @@ public class AttributeResource extends ExtendedObjectResource { @POST @Path("test") - public Response test(@QueryParam("deviceId") long deviceId, Attribute entity) { - Context.getPermissionsManager().checkAdmin(getUserId()); - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - Position last = Context.getIdentityManager().getLastPosition(deviceId); - if (last != null) { - Object result = new ComputedAttributesHandler( - Context.getConfig(), - Context.getIdentityManager(), - Context.getAttributesManager()).computeAttribute(entity, last); - if (result != null) { - switch (entity.getType()) { - case "number": - Number numberValue = (Number) result; - return Response.ok(numberValue).build(); - case "boolean": - Boolean booleanValue = (Boolean) result; - return Response.ok(booleanValue).build(); - default: - return Response.ok(result.toString()).build(); - } - } else { - return Response.noContent().build(); + public Response test(@QueryParam("deviceId") long deviceId, Attribute entity) throws StorageException { + permissionsService.checkAdmin(getUserId()); + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + + Device device = storage.getObject(Device.class, new Request( + new Columns.All(), + new Condition.Equals("id", "id", deviceId))); + if (device == null) { + throw new IllegalArgumentException("Device not found"); + } + + Position last = storage.getObject(Position.class, new Request( + new Columns.All(), + new Condition.Equals("id", "id", device.getPositionId()))); + if (last == null) { + throw new IllegalArgumentException("Device has no last position"); + } + + Object result = new ComputedAttributesHandler( + Context.getConfig(), + Context.getIdentityManager(), + Context.getAttributesManager()).computeAttribute(entity, last); + if (result != null) { + switch (entity.getType()) { + case "number": + Number numberValue = (Number) result; + return Response.ok(numberValue).build(); + case "boolean": + Boolean booleanValue = (Boolean) result; + return Response.ok(booleanValue).build(); + default: + return Response.ok(result.toString()).build(); } } else { - throw new IllegalArgumentException("Device has no last position"); + return Response.noContent().build(); } } @POST public Response add(Attribute entity) throws StorageException { - Context.getPermissionsManager().checkAdmin(getUserId()); + permissionsService.checkAdmin(getUserId()); return super.add(entity); } @Path("{id}") @PUT public Response update(Attribute entity) throws StorageException { - Context.getPermissionsManager().checkAdmin(getUserId()); + permissionsService.checkAdmin(getUserId()); return super.update(entity); } @Path("{id}") @DELETE public Response remove(@PathParam("id") long id) throws StorageException { - Context.getPermissionsManager().checkAdmin(getUserId()); + permissionsService.checkAdmin(getUserId()); return super.remove(id); } -- cgit v1.2.3 From b164114d23ad3d0f965c003489e31a6c0d78b0d3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 6 Apr 2022 19:54:32 -0700 Subject: Fix user creation --- src/main/java/org/traccar/database/UsersManager.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/traccar/database/UsersManager.java b/src/main/java/org/traccar/database/UsersManager.java index 31759dc8b..a54226cfe 100644 --- a/src/main/java/org/traccar/database/UsersManager.java +++ b/src/main/java/org/traccar/database/UsersManager.java @@ -59,6 +59,12 @@ public class UsersManager extends SimpleObjectManager { } } + @Override + public void addItem(User user) throws StorageException { + super.addItem(user); + getDataManager().updateUserPassword(user); + } + @Override public void updateItem(User user) throws StorageException { if (user.getHashedPassword() != null) { -- cgit v1.2.3 From b40358c4cee2e2d9b5b11b6264f4974c508a4ab9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Apr 2022 14:30:27 -0700 Subject: Add Envotech SLM protocol --- setup/default.xml | 1 + .../org/traccar/protocol/EnvotechProtocol.java | 39 ++++++++ .../traccar/protocol/EnvotechProtocolDecoder.java | 103 +++++++++++++++++++++ .../protocol/EnvotechProtocolDecoderTest.java | 24 +++++ 4 files changed, 167 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/EnvotechProtocol.java create mode 100644 src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 306421675..71e14f501 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -283,5 +283,6 @@ 5237 5238 5239 + 5240 diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocol.java b/src/main/java/org/traccar/protocol/EnvotechProtocol.java new file mode 100644 index 000000000..8eb71ee6b --- /dev/null +++ b/src/main/java/org/traccar/protocol/EnvotechProtocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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 EnvotechProtocol extends BaseProtocol { + + public EnvotechProtocol() { + 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 EnvotechProtocolDecoder(EnvotechProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java new file mode 100644 index 000000000..083d8a921 --- /dev/null +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -0,0 +1,103 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class EnvotechProtocolDecoder extends BaseProtocolDecoder { + + public EnvotechProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("$") + .number("dd") // mode + .expression("...,") // hardware + .number("(x+),") // event + .number("x+,") // group + .number("(x+),") // device id + .number("(dd)(dd)(dd)") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("xx") // connection status + .number("(dd)") // rssi + .number("d{5},") // mcc + .number("(ddd)") // power + .number("(ddd),") // battery + .number("(xx)") // inputs + .number("(xx),") // outputs + .number("(xxx)?,") // fuel + .number("(x{8}),") // status + .expression("[^']*'") + .number("(dd)(dd)(dd)") // date (ddmmyy) + .number("(dd)(dd)(dd)") // time (hhmmss) + .number("(d)") // fix + .number("(dd)(dd)(d+)([NS])") // latitude + .number("(ddd)(dd)(d+)([EW])") // longitude + .number("(ddd)") // speed + .number("(ddd)") // course + .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; + } + + Position position = new Position(getProtocolName()); + + position.set(Position.KEY_EVENT, parser.nextHexInt()); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + + position.setDeviceTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.KEY_POWER, parser.nextInt() * 0.01); + position.set(Position.KEY_BATTERY, parser.nextInt() * 0.01); + position.set(Position.KEY_INPUT, parser.nextHexInt()); + position.set(Position.PREFIX_OUT, parser.nextHexInt()); + position.set(Position.KEY_FUEL_LEVEL, parser.nextHexInt()); + position.set(Position.KEY_STATUS, parser.nextHexInt()); + + position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setValid(parser.nextInt() > 0); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); + position.setSpeed(parser.nextInt()); + position.setCourse(parser.nextInt()); + + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java new file mode 100644 index 000000000..6a455975d --- /dev/null +++ b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java @@ -0,0 +1,24 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class EnvotechProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = new EnvotechProtocolDecoder(null); + + verifyPosition(decoder, text( + "$80SLM,02,F,AB0010,130410155921,431750216,000040,0000,,00000000,'13041015592110476673N10111459E001281*2A")); + + verifyPosition(decoder, text( + "$80SLM,82,F,AB0010,130410155921,431750216,000040,0000,,00000000,'13041015592110476673N10111459E001281@B0,F,C456,038,00,M234567,,,1A2A3A4A5A6A*4E")); + + verifyPosition(decoder, text( + "$80SLM,60,000F,F016109,290322100445,AF2463902,000406,0000,000,00018780,54000000'29032209493500406302S03966062E000348*E637")); + + } + +} -- cgit v1.2.3 From 3241b83dc95fa151ac66dd88c102f08cc7cfaa7a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Apr 2022 16:42:21 -0700 Subject: Fix column rename issue --- schema/changelog-4.16.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/schema/changelog-4.16.xml b/schema/changelog-4.16.xml index adf8d4fc6..8bf3a41d5 100644 --- a/schema/changelog-4.16.xml +++ b/schema/changelog-4.16.xml @@ -16,11 +16,11 @@ - - + + - - + + -- cgit v1.2.3 From 517c6a5ad687bb627caa665452043dae3be52bcf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Apr 2022 11:10:05 -0700 Subject: Fix simple objects get --- src/main/java/org/traccar/api/SimpleObjectResource.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/SimpleObjectResource.java b/src/main/java/org/traccar/api/SimpleObjectResource.java index b55bf91e3..c61101077 100644 --- a/src/main/java/org/traccar/api/SimpleObjectResource.java +++ b/src/main/java/org/traccar/api/SimpleObjectResource.java @@ -43,7 +43,11 @@ public class SimpleObjectResource extends BaseObjectResourc if (all) { permissionsService.checkAdmin(getUserId()); } else { - permissionsService.checkUser(getUserId(), userId); + if (userId == 0) { + userId = getUserId(); + } else { + permissionsService.checkUser(getUserId(), userId); + } conditions.add(new Condition.Permission(User.class, userId, baseClass)); } -- cgit v1.2.3 From c2c58a30ae0857c4e584b128899baa63a684a892 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Apr 2022 13:18:43 -0700 Subject: Fix extended object resource --- src/main/java/org/traccar/api/ExtendedObjectResource.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index a12314a2c..40d679ded 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -46,7 +46,11 @@ public class ExtendedObjectResource extends BaseObjectResou if (all) { permissionsService.checkAdmin(getUserId()); } else { - permissionsService.checkUser(getUserId(), userId); + if (userId == 0) { + userId = getUserId(); + } else { + permissionsService.checkUser(getUserId(), userId); + } conditions.add(new Condition.Permission(User.class, userId, baseClass)); } -- cgit v1.2.3 From dd8fa719d7726489e76944029d2aed214ba8a904 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Apr 2022 15:37:33 -0700 Subject: Handle group permissions --- .../java/org/traccar/storage/DatabaseStorage.java | 112 ++++++++++++++++++--- .../java/org/traccar/storage/query/Condition.java | 46 ++++++++- 2 files changed, 141 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 4c985d98a..ff77ff8a8 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -15,6 +15,9 @@ */ package org.traccar.storage; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.model.GroupedModel; import org.traccar.model.Permission; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; @@ -43,7 +46,7 @@ public class DatabaseStorage extends Storage { public List getObjects(Class clazz, Request request) throws StorageException { StringBuilder query = new StringBuilder("SELECT "); query.append(formatColumns(request.getColumns(), clazz, "get", c -> c)); - query.append(" FROM ").append(getTableName(clazz)); + query.append(" FROM ").append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); query.append(formatOrder(request.getOrder())); query.append(formatLimit(request.getLimit())); @@ -61,7 +64,7 @@ public class DatabaseStorage extends Storage { @Override public long addObject(T entity, Request request) throws StorageException { StringBuilder query = new StringBuilder("INSERT INTO "); - query.append(getTableName(entity.getClass())); + query.append(getStorageName(entity.getClass())); query.append("("); query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c)); query.append(") VALUES ("); @@ -79,7 +82,7 @@ public class DatabaseStorage extends Storage { @Override public void updateObject(T entity, Request request) throws StorageException { StringBuilder query = new StringBuilder("UPDATE "); - query.append(getTableName(entity.getClass())); + query.append(getStorageName(entity.getClass())); query.append(" SET "); query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c + " = :" + c)); query.append(formatCondition(request.getCondition())); @@ -98,7 +101,7 @@ public class DatabaseStorage extends Storage { @Override public void removeObject(Class clazz, Request request) throws StorageException { StringBuilder query = new StringBuilder("DELETE FROM "); - query.append(getTableName(clazz)); + query.append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); try { QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); @@ -170,7 +173,7 @@ public class DatabaseStorage extends Storage { } } - private String getTableName(Class clazz) throws StorageException { + private String getStorageName(Class clazz) throws StorageException { StorageName storageName = clazz.getAnnotation(StorageName.class); if (storageName == null) { throw new StorageException("StorageName annotation is missing"); @@ -195,7 +198,11 @@ public class DatabaseStorage extends Storage { results.putAll(getConditionVariables(condition.getSecond())); } else if (genericCondition instanceof Condition.Permission) { var condition = (Condition.Permission) genericCondition; - results.put(Permission.getKey(condition.getOwnerClass()), condition.getOwnerId()); + if (condition.getOwnerId() > 0) { + results.put(Permission.getKey(condition.getOwnerClass()), condition.getOwnerId()); + } else { + results.put(Permission.getKey(condition.getPropertyClass()), condition.getPropertyId()); + } } return results; } @@ -205,11 +212,11 @@ public class DatabaseStorage extends Storage { return columns.getColumns(clazz, type).stream().map(mapper).collect(Collectors.joining(", ")); } - private String formatCondition(Condition genericCondition) { + private String formatCondition(Condition genericCondition) throws StorageException { return formatCondition(genericCondition, true); } - private String formatCondition(Condition genericCondition, boolean appendWhere) { + private String formatCondition(Condition genericCondition, boolean appendWhere) throws StorageException { StringBuilder result = new StringBuilder(); if (genericCondition != null) { if (appendWhere) { @@ -245,14 +252,8 @@ public class DatabaseStorage extends Storage { } else if (genericCondition instanceof Condition.Permission) { var condition = (Condition.Permission) genericCondition; - result.append("id IN (SELECT "); - result.append(Permission.getKey(condition.getPropertyClass())); - result.append(" FROM "); - result.append(Permission.getStorageName(condition.getOwnerClass(), condition.getPropertyClass())); - result.append(" WHERE "); - result.append(Permission.getKey(condition.getOwnerClass())); - result.append(" = :"); - result.append(Permission.getKey(condition.getOwnerClass())); + result.append("id IN ("); + result.append(formatPermissionQuery(condition)); result.append(")"); } @@ -281,4 +282,83 @@ public class DatabaseStorage extends Storage { return result.toString(); } + private String formatPermissionQuery(Condition.Permission condition) throws StorageException { + StringBuilder result = new StringBuilder(); + + String outputKey; + String conditionKey; + if (condition.getOwnerId() > 0) { + outputKey = Permission.getKey(condition.getPropertyClass()); + conditionKey = Permission.getKey(condition.getOwnerClass()); + } else { + outputKey = Permission.getKey(condition.getOwnerClass()); + conditionKey = Permission.getKey(condition.getPropertyClass()); + } + + result.append("SELECT "); + result.append(outputKey); + result.append(" FROM "); + result.append(Permission.getStorageName(condition.getOwnerClass(), condition.getPropertyClass())); + result.append(" WHERE "); + result.append(conditionKey); + result.append(" = :"); + result.append(conditionKey); + + if (condition.getIncludeGroups()) { + + boolean expandDevices; + String groupStorageName; + if (GroupedModel.class.isAssignableFrom(condition.getOwnerClass())) { + expandDevices = Device.class.isAssignableFrom(condition.getOwnerClass()); + groupStorageName = Permission.getStorageName(Group.class, condition.getPropertyClass()); + } else { + expandDevices = Device.class.isAssignableFrom(condition.getPropertyClass()); + groupStorageName = Permission.getStorageName(condition.getOwnerClass(), Group.class); + } + + result.append(" UNION "); + + result.append("SELECT DISTINCT "); + result.append(expandDevices? "devices." : "groups."); // TODO handle reverse search (e.g. users by device) + result.append(outputKey); + result.append(" FROM "); + result.append(groupStorageName); + + result.append(" INNER JOIN ("); + result.append("SELECT id as parentid, id as groupid FROM "); + result.append(getStorageName(Group.class)); + result.append(" UNION "); + result.append("SELECT groupid as parentid, id as groupid FROM "); + result.append(getStorageName(Group.class)); + result.append(" WHERE groupid IS NOT NULL"); + result.append(" UNION "); + result.append("SELECT g2.groupid as parentid, g1.id as groupid FROM "); + result.append(getStorageName(Group.class)); + result.append(" AS g2"); + result.append(" INNER JOIN "); + result.append(getStorageName(Group.class)); + result.append(" AS g1 ON g2.id = g1.groupid"); + result.append(" WHERE g2.groupid IS NOT NULL"); + result.append(") AS groups ON "); + result.append(groupStorageName); + result.append(".groupid = groups.parentid"); + + if (expandDevices) { + result.append(" INNER JOIN ("); + result.append("SELECT groupid as parentid, id as deviceid FROM "); + result.append(getStorageName(Device.class)); + result.append(" WHERE groupid IS NOT NULL"); + result.append(") AS devices ON groups.groupid = devices.parentid"); + } + + result.append(" WHERE "); + result.append(conditionKey); // TODO handle search for device / group + result.append(" = :"); + result.append(conditionKey); + + } + + return result.toString(); + } + } diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 304440698..91ede236c 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -1,5 +1,22 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage.query; +import org.traccar.model.GroupedModel; + import java.util.List; public interface Condition { @@ -132,11 +149,28 @@ public interface Condition { private final Class ownerClass; private final long ownerId; private final Class propertyClass; + private final long propertyId; + private final boolean excludeGroups; - public Permission(Class ownerClass, long ownerId, Class propertyClass) { + private Permission( + Class ownerClass, long ownerId, Class propertyClass, long propertyId, boolean excludeGroups) { this.ownerClass = ownerClass; this.ownerId = ownerId; this.propertyClass = propertyClass; + this.propertyId = propertyId; + this.excludeGroups = excludeGroups; + } + + public Permission(Class ownerClass, long ownerId, Class propertyClass) { + this(ownerClass, ownerId, propertyClass, 0, false); + } + + public Permission(Class ownerClass, Class propertyClass, long propertyId) { + this(ownerClass, 0, propertyClass, propertyId, false); + } + + public Permission excludeGroups() { + return new Permission(this.ownerClass, this.ownerId, this.propertyClass, this.propertyId, true); } public Class getOwnerClass() { @@ -150,6 +184,16 @@ public interface Condition { public Class getPropertyClass() { return propertyClass; } + + public long getPropertyId() { + return propertyId; + } + + public boolean getIncludeGroups() { + boolean ownerGroupModel = GroupedModel.class.isAssignableFrom(ownerClass); + boolean propertyGroupModel = GroupedModel.class.isAssignableFrom(propertyClass); + return (ownerGroupModel || propertyGroupModel) && !excludeGroups; + } } } -- cgit v1.2.3 From 5fe089626bd367241d3424a0b71dee87805673ca Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Apr 2022 19:51:37 -0700 Subject: Fix nested permission check --- .../traccar/api/security/PermissionsService.java | 26 +++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index e39b8808f..c640f8d74 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -15,6 +15,7 @@ */ package org.traccar.api.security; +import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Command; import org.traccar.model.Device; @@ -99,8 +100,7 @@ public class PermissionsService { if (object instanceof GroupedModel) { long groupId = ((GroupedModel) object).getGroupId(); if (groupId > 0) { - denied = storage.getPermissions(User.class, userId, Group.class, groupId).isEmpty(); - // TODO TEST NESTED GROUP PERMISSION + checkPermission(Group.class, userId, groupId); } } if (object instanceof ScheduledModel) { @@ -124,12 +124,22 @@ public class PermissionsService { } } - public void checkPermission( - Class clazz, long userId, long objectId) throws StorageException, SecurityException { - if (!getUser(userId).getAdministrator() - && storage.getPermissions(User.class, userId, clazz, objectId).isEmpty()) { - // TODO handle nested objects - throw new SecurityException(clazz.getSimpleName() + " access denied"); + public void checkPermission( + Class clazz, long userId, long objectId) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator()) { + var objects = storage.getObjects(clazz, new Request( + new Columns.Include("id"), + new Condition.Permission(User.class, userId, clazz))); + boolean found = false; + for (var object : objects) { + if (object.getId() == objectId) { + found = true; + break; + } + } + if (!found) { + throw new SecurityException(clazz.getSimpleName() + " access denied"); + } } } -- cgit v1.2.3 From 9c9f5d66147cfa428ea18dd29103b9c82e529dca Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Apr 2022 19:53:09 -0700 Subject: Add license notices --- src/main/java/org/traccar/storage/MemoryStorage.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/Storage.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/StorageException.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/StorageName.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/query/Columns.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/query/Limit.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/query/Order.java | 15 +++++++++++++++ src/main/java/org/traccar/storage/query/Request.java | 15 +++++++++++++++ 8 files changed, 120 insertions(+) diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java index 115bbea7a..71e895428 100644 --- a/src/main/java/org/traccar/storage/MemoryStorage.java +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage; import org.traccar.model.Pair; diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java index 3b27f57e9..22b5aaedc 100644 --- a/src/main/java/org/traccar/storage/Storage.java +++ b/src/main/java/org/traccar/storage/Storage.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage; import org.traccar.model.Permission; diff --git a/src/main/java/org/traccar/storage/StorageException.java b/src/main/java/org/traccar/storage/StorageException.java index 6c1e9c2ff..3f066cae6 100644 --- a/src/main/java/org/traccar/storage/StorageException.java +++ b/src/main/java/org/traccar/storage/StorageException.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage; public class StorageException extends Exception { diff --git a/src/main/java/org/traccar/storage/StorageName.java b/src/main/java/org/traccar/storage/StorageName.java index b6fa55e02..bf824c333 100644 --- a/src/main/java/org/traccar/storage/StorageName.java +++ b/src/main/java/org/traccar/storage/StorageName.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage; import java.lang.annotation.ElementType; diff --git a/src/main/java/org/traccar/storage/query/Columns.java b/src/main/java/org/traccar/storage/query/Columns.java index 196d2281c..97ca13be9 100644 --- a/src/main/java/org/traccar/storage/query/Columns.java +++ b/src/main/java/org/traccar/storage/query/Columns.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage.query; import org.traccar.storage.QueryExtended; diff --git a/src/main/java/org/traccar/storage/query/Limit.java b/src/main/java/org/traccar/storage/query/Limit.java index 4a20f0ce2..9673e5426 100644 --- a/src/main/java/org/traccar/storage/query/Limit.java +++ b/src/main/java/org/traccar/storage/query/Limit.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage.query; public class Limit { diff --git a/src/main/java/org/traccar/storage/query/Order.java b/src/main/java/org/traccar/storage/query/Order.java index 6852c5ba8..d12acc83b 100644 --- a/src/main/java/org/traccar/storage/query/Order.java +++ b/src/main/java/org/traccar/storage/query/Order.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage.query; public class Order { diff --git a/src/main/java/org/traccar/storage/query/Request.java b/src/main/java/org/traccar/storage/query/Request.java index a98dd48f7..41aa37bf1 100644 --- a/src/main/java/org/traccar/storage/query/Request.java +++ b/src/main/java/org/traccar/storage/query/Request.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage.query; public class Request { -- cgit v1.2.3 From 437a7651096ecdd8e9cabeeca760b9af89b10458 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Apr 2022 18:03:32 -0700 Subject: Refactor services --- src/main/java/org/traccar/LifecycleObject.java | 21 +++++++++++++++++++++ src/main/java/org/traccar/Main.java | 21 ++++++++++++++------- src/main/java/org/traccar/ServerManager.java | 4 +++- src/main/java/org/traccar/TrackerConnector.java | 6 +----- .../java/org/traccar/schedule/ScheduleManager.java | 12 ++++++------ src/main/java/org/traccar/web/WebServer.java | 7 +++++-- 6 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/traccar/LifecycleObject.java diff --git a/src/main/java/org/traccar/LifecycleObject.java b/src/main/java/org/traccar/LifecycleObject.java new file mode 100644 index 000000000..7af21d528 --- /dev/null +++ b/src/main/java/org/traccar/LifecycleObject.java @@ -0,0 +1,21 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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; + +public interface LifecycleObject { + void start() throws Exception; + void stop(); +} diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 63e5c1f90..570f3c6ad 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -27,6 +27,9 @@ import java.lang.management.MemoryMXBean; import java.lang.management.OperatingSystemMXBean; import java.lang.management.RuntimeMXBean; import java.nio.charset.Charset; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; import java.util.Timer; @@ -123,11 +126,16 @@ public final class Main { LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); LOGGER.info("Starting server..."); - Context.getServerManager().start(); + List services = new LinkedList<>(); + services.add(Context.getServerManager()); if (Context.getWebServer() != null) { - Context.getWebServer().start(); + services.add(Context.getWebServer()); + } + services.add(Context.getScheduleManager()); + + for (LifecycleObject service : services) { + service.start(); } - Context.getScheduleManager().start(); scheduleHealthCheck(); @@ -136,11 +144,10 @@ public final class Main { Runtime.getRuntime().addShutdownHook(new Thread(() -> { LOGGER.info("Shutting down server..."); - Context.getScheduleManager().stop(); - if (Context.getWebServer() != null) { - Context.getWebServer().stop(); + Collections.reverse(services); + for (LifecycleObject service : services) { + service.stop(); } - Context.getServerManager().stop(); })); } catch (Exception e) { LOGGER.error("Main method error", e); diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 2e2cf7cff..15faf9f2b 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -29,7 +29,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -public class ServerManager { +public class ServerManager implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(ServerManager.class); @@ -50,6 +50,7 @@ public class ServerManager { return protocolList.get(name); } + @Override public void start() throws Exception { for (TrackerConnector connector: connectorList) { try { @@ -62,6 +63,7 @@ public class ServerManager { } } + @Override public void stop() { for (TrackerConnector connector: connectorList) { connector.stop(); diff --git a/src/main/java/org/traccar/TrackerConnector.java b/src/main/java/org/traccar/TrackerConnector.java index 9e2d27ae5..fc6e93399 100644 --- a/src/main/java/org/traccar/TrackerConnector.java +++ b/src/main/java/org/traccar/TrackerConnector.java @@ -17,7 +17,7 @@ package org.traccar; import io.netty.channel.group.ChannelGroup; -public interface TrackerConnector { +public interface TrackerConnector extends LifecycleObject { boolean isDatagram(); @@ -25,8 +25,4 @@ public interface TrackerConnector { ChannelGroup getChannelGroup(); - void start() throws Exception; - - void stop(); - } diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index 5d5054100..d43285451 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,29 +15,29 @@ */ package org.traccar.schedule; +import org.traccar.LifecycleObject; + import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -public class ScheduleManager { +public class ScheduleManager implements LifecycleObject { private ScheduledExecutorService executor; + @Override public void start() { - executor = Executors.newSingleThreadScheduledExecutor(); new TaskDeviceInactivityCheck().schedule(executor); new TaskWebSocketKeepalive().schedule(executor); - } + @Override public void stop() { - if (executor != null) { executor.shutdown(); executor = null; } - } } diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 932781156..0ed5d013e 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,7 @@ import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.LifecycleObject; import org.traccar.Main; import org.traccar.api.DateParameterConverterProvider; import org.traccar.config.Config; @@ -69,7 +70,7 @@ import java.io.Writer; import java.net.InetSocketAddress; import java.util.EnumSet; -public class WebServer { +public class WebServer implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); @@ -238,6 +239,7 @@ public class WebServer { } } + @Override public void start() { try { server.start(); @@ -246,6 +248,7 @@ public class WebServer { } } + @Override public void stop() { try { server.stop(); -- cgit v1.2.3 From f5dcafaf60fd41c5a2cd587e9ecf40e67d235d59 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Apr 2022 18:10:56 -0700 Subject: Use schedule manager for health check --- src/main/java/org/traccar/Main.java | 12 ------ .../java/org/traccar/api/HealthCheckService.java | 47 ++++++++++------------ .../java/org/traccar/schedule/ScheduleManager.java | 2 + 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 570f3c6ad..6daf72bb4 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -19,7 +19,6 @@ import com.google.inject.Guice; import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.api.HealthCheckService; import java.io.File; import java.lang.management.ManagementFactory; @@ -31,7 +30,6 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Timer; public final class Main { @@ -110,14 +108,6 @@ public final class Main { } } - private static void scheduleHealthCheck() { - HealthCheckService service = new HealthCheckService(); - if (service.isEnabled()) { - new Timer().scheduleAtFixedRate( - service.createTask(), service.getPeriod(), service.getPeriod()); - } - } - public static void run(String configFile) { try { Context.init(configFile); @@ -137,8 +127,6 @@ public final class Main { service.start(); } - scheduleHealthCheck(); - Thread.setDefaultUncaughtExceptionHandler((t, e) -> LOGGER.error("Thread exception", e)); Runtime.getRuntime().addShutdownHook(new Thread(() -> { diff --git a/src/main/java/org/traccar/api/HealthCheckService.java b/src/main/java/org/traccar/api/HealthCheckService.java index 0182cc358..8a17c8798 100644 --- a/src/main/java/org/traccar/api/HealthCheckService.java +++ b/src/main/java/org/traccar/api/HealthCheckService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@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,10 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.config.Keys; -import java.util.TimerTask; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; -public class HealthCheckService { +public class HealthCheckService implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(HealthCheckService.class); @@ -52,36 +53,30 @@ public class HealthCheckService { } } - public boolean isEnabled() { - return enabled; - } - - public long getPeriod() { - return period; - } - private String getUrl() { String address = Context.getConfig().getString(Keys.WEB_ADDRESS, "localhost"); int port = Context.getConfig().getInteger(Keys.WEB_PORT); return "http://" + address + ":" + port + "/api/server"; } - public TimerTask createTask() { - return new TimerTask() { - @Override - public void run() { - LOGGER.debug("Health check running"); - int status = Context.getClient().target(getUrl()).request().get().getStatus(); - if (status == 200) { - int result = systemD.sd_notify(0, "WATCHDOG=1"); - if (result < 0) { - LOGGER.warn("Health check notify error {}", result); - } - } else { - LOGGER.warn("Health check failed with status {}", status); - } + public void schedule(ScheduledExecutorService executor) { + if (enabled) { + executor.scheduleAtFixedRate(this, period, period, TimeUnit.MILLISECONDS); + } + } + + @Override + public void run() { + LOGGER.debug("Health check running"); + int status = Context.getClient().target(getUrl()).request().get().getStatus(); + if (status == 200) { + int result = systemD.sd_notify(0, "WATCHDOG=1"); + if (result < 0) { + LOGGER.warn("Health check notify error {}", result); } - }; + } else { + LOGGER.warn("Health check failed with status {}", status); + } } interface SystemD extends Library { diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index d43285451..a1679717f 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -16,6 +16,7 @@ package org.traccar.schedule; import org.traccar.LifecycleObject; +import org.traccar.api.HealthCheckService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -30,6 +31,7 @@ public class ScheduleManager implements LifecycleObject { new TaskDeviceInactivityCheck().schedule(executor); new TaskWebSocketKeepalive().schedule(executor); + new HealthCheckService().schedule(executor); } @Override -- cgit v1.2.3 From ef8cfea50d6ca763a4af6eb75287325e91f5f5ca Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Apr 2022 18:12:10 -0700 Subject: Change health check package --- .../java/org/traccar/api/HealthCheckService.java | 87 ---------------------- .../java/org/traccar/schedule/ScheduleManager.java | 3 +- .../java/org/traccar/schedule/TaskHealthCheck.java | 87 ++++++++++++++++++++++ 3 files changed, 88 insertions(+), 89 deletions(-) delete mode 100644 src/main/java/org/traccar/api/HealthCheckService.java create mode 100644 src/main/java/org/traccar/schedule/TaskHealthCheck.java diff --git a/src/main/java/org/traccar/api/HealthCheckService.java b/src/main/java/org/traccar/api/HealthCheckService.java deleted file mode 100644 index 8a17c8798..000000000 --- a/src/main/java/org/traccar/api/HealthCheckService.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2020 - 2022 Anton Tananaev (anton@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.api; - -import com.sun.jna.Library; -import com.sun.jna.Native; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.config.Keys; - -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -public class HealthCheckService implements Runnable { - - private static final Logger LOGGER = LoggerFactory.getLogger(HealthCheckService.class); - - private SystemD systemD; - - private boolean enabled; - private long period; - - public HealthCheckService() { - if (!Context.getConfig().getBoolean(Keys.WEB_DISABLE_HEALTH_CHECK) - && System.getProperty("os.name").toLowerCase().startsWith("linux")) { - try { - systemD = Native.load("systemd", SystemD.class); - String watchdogTimer = System.getenv("WATCHDOG_USEC"); - if (watchdogTimer != null && !watchdogTimer.isEmpty()) { - period = Long.parseLong(watchdogTimer) / 1000 * 4 / 5; - } - if (period > 0) { - LOGGER.info("Health check enabled with period {}", period); - enabled = true; - } - } catch (UnsatisfiedLinkError e) { - LOGGER.warn("No systemd support", e); - } - } - } - - private String getUrl() { - String address = Context.getConfig().getString(Keys.WEB_ADDRESS, "localhost"); - int port = Context.getConfig().getInteger(Keys.WEB_PORT); - return "http://" + address + ":" + port + "/api/server"; - } - - public void schedule(ScheduledExecutorService executor) { - if (enabled) { - executor.scheduleAtFixedRate(this, period, period, TimeUnit.MILLISECONDS); - } - } - - @Override - public void run() { - LOGGER.debug("Health check running"); - int status = Context.getClient().target(getUrl()).request().get().getStatus(); - if (status == 200) { - int result = systemD.sd_notify(0, "WATCHDOG=1"); - if (result < 0) { - LOGGER.warn("Health check notify error {}", result); - } - } else { - LOGGER.warn("Health check failed with status {}", status); - } - } - - interface SystemD extends Library { - @SuppressWarnings("checkstyle:MethodName") - int sd_notify(@SuppressWarnings("checkstyle:ParameterName") int unset_environment, String state); - } - -} diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index a1679717f..7a3d33b85 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -16,7 +16,6 @@ package org.traccar.schedule; import org.traccar.LifecycleObject; -import org.traccar.api.HealthCheckService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -31,7 +30,7 @@ public class ScheduleManager implements LifecycleObject { new TaskDeviceInactivityCheck().schedule(executor); new TaskWebSocketKeepalive().schedule(executor); - new HealthCheckService().schedule(executor); + new TaskHealthCheck().schedule(executor); } @Override diff --git a/src/main/java/org/traccar/schedule/TaskHealthCheck.java b/src/main/java/org/traccar/schedule/TaskHealthCheck.java new file mode 100644 index 000000000..087cd3e63 --- /dev/null +++ b/src/main/java/org/traccar/schedule/TaskHealthCheck.java @@ -0,0 +1,87 @@ +/* + * Copyright 2020 - 2022 Anton Tananaev (anton@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.schedule; + +import com.sun.jna.Library; +import com.sun.jna.Native; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.Context; +import org.traccar.config.Keys; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public class TaskHealthCheck implements Runnable { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaskHealthCheck.class); + + private SystemD systemD; + + private boolean enabled; + private long period; + + public TaskHealthCheck() { + if (!Context.getConfig().getBoolean(Keys.WEB_DISABLE_HEALTH_CHECK) + && System.getProperty("os.name").toLowerCase().startsWith("linux")) { + try { + systemD = Native.load("systemd", SystemD.class); + String watchdogTimer = System.getenv("WATCHDOG_USEC"); + if (watchdogTimer != null && !watchdogTimer.isEmpty()) { + period = Long.parseLong(watchdogTimer) / 1000 * 4 / 5; + } + if (period > 0) { + LOGGER.info("Health check enabled with period {}", period); + enabled = true; + } + } catch (UnsatisfiedLinkError e) { + LOGGER.warn("No systemd support", e); + } + } + } + + private String getUrl() { + String address = Context.getConfig().getString(Keys.WEB_ADDRESS, "localhost"); + int port = Context.getConfig().getInteger(Keys.WEB_PORT); + return "http://" + address + ":" + port + "/api/server"; + } + + public void schedule(ScheduledExecutorService executor) { + if (enabled) { + executor.scheduleAtFixedRate(this, period, period, TimeUnit.MILLISECONDS); + } + } + + @Override + public void run() { + LOGGER.debug("Health check running"); + int status = Context.getClient().target(getUrl()).request().get().getStatus(); + if (status == 200) { + int result = systemD.sd_notify(0, "WATCHDOG=1"); + if (result < 0) { + LOGGER.warn("Health check notify error {}", result); + } + } else { + LOGGER.warn("Health check failed with status {}", status); + } + } + + interface SystemD extends Library { + @SuppressWarnings("checkstyle:MethodName") + int sd_notify(@SuppressWarnings("checkstyle:ParameterName") int unset_environment, String state); + } + +} -- cgit v1.2.3 From ade1d98a4ee19265acff946716d6f5a6af5ce58d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Apr 2022 17:25:05 -0700 Subject: Add battery level test --- tools/test-generator.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/test-generator.py b/tools/test-generator.py index ca7871e1d..b8a06ac32 100755 --- a/tools/test-generator.py +++ b/tools/test-generator.py @@ -35,12 +35,14 @@ for i in range(0, len(waypoints)): lon = lon1 + (lon2 - lon1) * j / count points.append((lat, lon)) -def send(conn, lat, lon, course, speed, alarm, ignition, accuracy, rpm, fuel, driverUniqueId): - params = (('id', id), ('timestamp', int(time.time())), ('lat', lat), ('lon', lon), ('bearing', course), ('speed', speed)) +def send(conn, lat, lon, course, speed, battery, alarm, ignition, accuracy, rpm, fuel, driverUniqueId): + params = (('id', id), ('timestamp', int(time.time())), ('lat', lat), ('lon', lon), ('bearing', course), ('speed', speed), ('batt', battery)) if alarm: params = params + (('alarm', 'sos'),) if ignition: params = params + (('ignition', 'true'),) + else: + params = params + (('ignition', 'false'),) if accuracy: params = params + (('accuracy', accuracy),) if rpm: @@ -70,11 +72,12 @@ while True: (lat2, lon2) = points[(index + 1) % len(points)] speed = device_speed if (index % len(points)) != 0 else 0 alarm = (index % 10) == 0 + battery = random.randint(0, 100) ignition = (index % len(points)) != 0 accuracy = 100 if (index % 10) == 0 else 0 rpm = random.randint(500, 4000) fuel = random.randint(0, 80) driverUniqueId = driver_id if (index % len(points)) == 0 else False - send(conn, lat1, lon1, course(lat1, lon1, lat2, lon2), speed, alarm, ignition, accuracy, rpm, fuel, driverUniqueId) + send(conn, lat1, lon1, course(lat1, lon1, lat2, lon2), speed, battery, alarm, ignition, accuracy, rpm, fuel, driverUniqueId) time.sleep(period) index += 1 -- cgit v1.2.3 From f1b3036ab53cc6083ff644990249bf3a75969f70 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Apr 2022 18:18:35 -0700 Subject: Add Suntech universal commands --- .../traccar/protocol/SuntechProtocolDecoder.java | 7 ++ .../traccar/protocol/SuntechProtocolEncoder.java | 92 ++++++++++++++++------ 2 files changed, 76 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 2f8e50c5e..8926f427e 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -44,6 +44,7 @@ import java.util.TimeZone; public class SuntechProtocolDecoder extends BaseProtocolDecoder { + private boolean universal; private String prefix; private int protocolType; @@ -58,6 +59,10 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + public boolean getUniversal() { + return universal; + } + public String getPrefix() { return prefix; } @@ -831,6 +836,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (buf.getByte(buf.readerIndex() + 1) == 0) { + universal = true; return decodeBinary(channel, remoteAddress, buf); } else { @@ -841,6 +847,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (prefix.equals("CRR")) { return decodeCrashReport(channel, remoteAddress, buf); } else if (prefix.length() < 5) { + universal = true; return decodeUniversal(channel, remoteAddress, values); } else if (prefix.endsWith("HTE")) { return decodeTravelReport(channel, remoteAddress, values); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java index 3b4995110..597acaae8 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,49 +27,95 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { super(protocol); } - private String getPrefix(Channel channel) { - String prefix = "SA200CMD"; + @Override + protected Object encodeCommand(Channel channel, Command command) { + + boolean universal = false; + String prefix = "SA200"; if (channel != null) { SuntechProtocolDecoder protocolDecoder = BasePipelineFactory.getHandler(channel.pipeline(), SuntechProtocolDecoder.class); if (protocolDecoder != null) { + universal = protocolDecoder.getUniversal(); String decoderPrefix = protocolDecoder.getPrefix(); if (decoderPrefix != null && decoderPrefix.length() > 5) { - prefix = decoderPrefix.substring(0, decoderPrefix.length() - 3) + "CMD"; + prefix = decoderPrefix.substring(0, decoderPrefix.length() - 3); } } } - return prefix; - } - - @Override - protected Object encodeCommand(Channel channel, Command command) { - String prefix = getPrefix(channel); + if (universal) { + return encodeUniversalCommand(channel, command); + } else { + return encodeLegacyCommand(channel, prefix, command); + } + } + protected Object encodeUniversalCommand(Channel channel, Command command) { switch (command.getType()) { case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, prefix + ";%s;02;Reboot\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, "CMD;%s;03;03\r", Command.KEY_UNIQUE_ID); case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, prefix + ";%s;02;\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, "CMD;%s;03;01\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: - if (command.getAttributes().containsKey(Command.KEY_DATA)) { - if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { - return formatCommand(command, prefix + ";%s;02;Enable%s\r", - Command.KEY_UNIQUE_ID, Command.KEY_INDEX); - } else { - return formatCommand(command, prefix + ";%s;02;Disable%s\r", - Command.KEY_UNIQUE_ID, Command.KEY_INDEX); + if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { + switch (command.getString(Command.KEY_INDEX)) { + case "1": + return formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); + case "2": + return formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); + case "3": + return formatCommand(command, "CMD;%s;04;09\r", Command.KEY_UNIQUE_ID); + default: + return null; } + } else { + switch (command.getString(Command.KEY_INDEX)) { + case "1": + return formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); + case "2": + return formatCommand(command, "CMD;%s;04;04\r", Command.KEY_UNIQUE_ID); + case "3": + return formatCommand(command, "CMD;%s;04;10\r", Command.KEY_UNIQUE_ID); + default: + return null; + } + } + case Command.TYPE_ENGINE_STOP: + return formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME: + return formatCommand(command, "CMD;%s;02;02\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_ARM: + return formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_DISARM: + return formatCommand(command, "CMD;%s;04;04\r", Command.KEY_UNIQUE_ID); + default: + return null; + } + } + + protected Object encodeLegacyCommand(Channel channel, String prefix, Command command) { + switch (command.getType()) { + case Command.TYPE_REBOOT_DEVICE: + return formatCommand(command, prefix + "CMD;%s;02;Reboot\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_SINGLE: + return formatCommand(command, prefix + "CMD;%s;02;\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_OUTPUT_CONTROL: + if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { + return formatCommand(command, prefix + "CMD;%s;02;Enable%s\r", + Command.KEY_UNIQUE_ID, Command.KEY_INDEX); + } else { + return formatCommand(command, prefix + "CMD;%s;02;Disable%s\r", + Command.KEY_UNIQUE_ID, Command.KEY_INDEX); } case Command.TYPE_ENGINE_STOP: - return formatCommand(command, prefix + ";%s;02;Enable1\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, prefix + "CMD;%s;02;Enable1\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, prefix + ";%s;02;Disable1\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, prefix + "CMD;%s;02;Disable1\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ALARM_ARM: - return formatCommand(command, prefix + ";%s;02;Enable2\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, prefix + "CMD;%s;02;Enable2\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ALARM_DISARM: - return formatCommand(command, prefix + ";%s;02;Disable2\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, prefix + "CMD;%s;02;Disable2\r", Command.KEY_UNIQUE_ID); default: return null; } -- cgit v1.2.3 From b574e5398a1dd4b4bd17b4b6d3023331dbf43882 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Apr 2022 20:48:08 -0700 Subject: Support VXT-01 protocol --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 117 ++++++++++++++------- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 4 + 2 files changed, 81 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 4d3448e84..feacc1ae8 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -113,6 +113,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_MULTIMEDIA_2 = 0x41; public static final int MSG_ALARM = 0x95; + private enum Variant { + VXT01, + STANDARD, + } + + private Variant variant; + private static boolean isSupported(int type) { return hasGps(type) || hasLbs(type) || hasStatus(type); } @@ -333,8 +340,15 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case 4: position.set(Position.KEY_ALARM, Position.ALARM_SOS); break; + case 6: + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); + break; case 7: - position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + if (variant == Variant.VXT01) { + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + } else { + position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + } break; default: break; @@ -346,7 +360,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); } position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); return true; } @@ -445,7 +458,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } - private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { int length = buf.readUnsignedByte(); int dataLength = length - 5; @@ -903,44 +916,47 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (hasStatus(type)) { decodeStatus(position, buf, true); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); } - if (type == MSG_GPS_LBS_1 && buf.readableBytes() > 75 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); - buf.readUnsignedByte(); // alarm - buf.readUnsignedByte(); // swiped - position.set("driverLicense", data.trim()); - } - - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 18) { - decodeStatus(position, buf, false); - position.set("oil", buf.readUnsignedShort()); - int temperature = buf.readUnsignedByte(); - if (BitUtil.check(temperature, 7)) { - temperature = -BitUtil.to(temperature, 7); - } - position.set(Position.PREFIX_TEMP + 1, temperature); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 10); - } - - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 2 + 6) { - int mask = buf.readUnsignedShort(); - position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); - position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); - if (BitUtil.check(mask, 8 + 4)) { - int value = BitUtil.to(mask, 8 + 1); - if (BitUtil.check(mask, 8 + 1)) { - value = -value; - } - position.set(Position.PREFIX_TEMP + 1, value); - } else { - int value = BitUtil.to(mask, 8 + 2); - if (BitUtil.check(mask, 8 + 5)) { - position.set(Position.PREFIX_ADC + 1, value); + if (type == MSG_GPS_LBS_1) { + if (buf.readableBytes() > 75 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); + buf.readUnsignedByte(); // alarm + buf.readUnsignedByte(); // swiped + position.set("driverLicense", data.trim()); + } else if (buf.readableBytes() == 8) { + int mask = buf.readUnsignedShort(); + position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); + position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); + if (BitUtil.check(mask, 8 + 4)) { + int value = BitUtil.to(mask, 8 + 1); + if (BitUtil.check(mask, 8 + 1)) { + value = -value; + } + position.set(Position.PREFIX_TEMP + 1, value); } else { - position.set(Position.PREFIX_ADC + 1, value * 0.1); + int value = BitUtil.to(mask, 8 + 2); + if (BitUtil.check(mask, 8 + 5)) { + position.set(Position.PREFIX_ADC + 1, value); + } else { + position.set(Position.PREFIX_ADC + 1, value * 0.1); + } } + } else if (buf.readableBytes() == 11) { + decodeStatus(position, buf, false); + buf.readUnsignedByte(); // alarm extension + } else if (buf.readableBytes() == 18) { + decodeStatus(position, buf, false); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + position.set("oil", buf.readUnsignedShort()); + int temperature = buf.readUnsignedByte(); + if (BitUtil.check(temperature, 7)) { + temperature = -BitUtil.to(temperature, 7); + } + position.set(Position.PREFIX_TEMP + 1, temperature); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 10); } } @@ -1354,21 +1370,42 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } + private void decodeVariant(ByteBuf buf) { + int header = buf.getUnsignedShort(buf.readerIndex()); + int length; + int type; + if (header == 0x7878) { + length = buf.getUnsignedByte(buf.readerIndex() + 2); + type = buf.getUnsignedByte(buf.readerIndex() + 2 + 1); + } else { + length = buf.getUnsignedShort(buf.readerIndex() + 2); + type = buf.getUnsignedByte(buf.readerIndex() + 2 + 2); + } + + if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x24) { + variant = Variant.VXT01; + } else if (header == 0x7878 && type == MSG_GPS_LBS_STATUS_1 && length == 0x24) { + variant = Variant.VXT01; + } else { + variant = Variant.STANDARD; + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; + decodeVariant(buf); + int header = buf.readShort(); if (header == 0x7878) { return decodeBasic(channel, remoteAddress, buf); - } else if (header == 0x7979) { + } else { return decodeExtended(channel, remoteAddress, buf); } - - return null; } } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index ad65ec960..b65b6709e 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "7878241216040e102c22cf00915ffb04c6016300195a02d402283b00753f400571040001dda4880d0a"), + Position.KEY_IGNITION, false); + verifyNotNull(decoder, binary( "787831241603060c231e000194620213ee00606a3413ee0060692e000000000000000000000000000000000000000000003a0cb70d0a")); -- cgit v1.2.3 From fe50b376ee5bee1a738aef3baca97e56f75633a4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Apr 2022 16:58:46 -0700 Subject: Clean up alarm commands --- src/main/java/org/traccar/model/Command.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/model/Command.java b/src/main/java/org/traccar/model/Command.java index 03961c7b2..49486bdbc 100644 --- a/src/main/java/org/traccar/model/Command.java +++ b/src/main/java/org/traccar/model/Command.java @@ -58,11 +58,10 @@ public class Command extends Message implements Cloneable { public static final String TYPE_GET_MODEM_STATUS = "getModemStatus"; public static final String TYPE_GET_DEVICE_STATUS = "getDeviceStatus"; public static final String TYPE_SET_SPEED_LIMIT = "setSpeedLimit"; - public static final String TYPE_MODE_POWER_SAVING = "modePowerSaving"; public static final String TYPE_MODE_DEEP_SLEEP = "modeDeepSleep"; - public static final String TYPE_ALARM_GEOFENCE = "movementAlarm"; + public static final String TYPE_ALARM_GEOFENCE = "alarmGeofence"; public static final String TYPE_ALARM_BATTERY = "alarmBattery"; public static final String TYPE_ALARM_SOS = "alarmSos"; public static final String TYPE_ALARM_REMOVE = "alarmRemove"; -- cgit v1.2.3 From 259c6fe4aa0132ae8d6ca6eb63c82e8ef64d8a6a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Apr 2022 17:02:30 -0700 Subject: Integer index --- src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java index c34674128..d507f3c4f 100644 --- a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java @@ -271,7 +271,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SOS_NUMBER); - command.set(Command.KEY_INDEX, "0"); + command.set(Command.KEY_INDEX, 0); command.set(Command.KEY_PHONE, "+55555555555"); command.set(Command.KEY_DEVICE_PASSWORD, "232323"); -- cgit v1.2.3 From ffc1b33d5d15068294aecc64dbeae20dd77d972d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Apr 2022 17:36:51 -0700 Subject: Huabao speeding alarm --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 5 ++++- src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 0ae08af37..b0ad9a229 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -122,6 +122,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { || BitUtil.check(value, 10) || BitUtil.check(value, 11)) { return Position.ALARM_FAULT; } + if (BitUtil.check(value, 7)) { + return Position.ALARM_LOW_BATTERY; + } if (BitUtil.check(value, 8)) { return Position.ALARM_POWER_OFF; } diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 7aaec33e7..8ba6fcaf1 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7E01000021013345678906000F002C012F373031313142534A2D4D3742203030303030303001D4C1423838383838B47E")); + verifyAttribute(decoder, binary( + "7E020000480123456789010013000000800000000301597BC506CBFF6600EB00000155210726203531010400000000EB24000C00B28986047701207027150200060089FFFFEFFF0004002D0E10000600C5FFFFFFEF697E"), + Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + verifyAttribute(decoder, binary( "7e0200008e01917159043700b300000000800000030158990606ca0fd7000400000000211129111705010400000000cc14383938363037423831303230393031363239363830010d8001aa81021388820200858301148401aa8502189b8601338702007e8801338901148a0200998b1131323334353637383941424344454647488c04000200a88d0200828e0114a00b50353338662c5530323966037e"), Position.KEY_DTCS, "P538f U029f"); -- cgit v1.2.3 From 82ab794c56d98a1aae8ea261ee709fecac9fbc54 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Apr 2022 17:46:00 -0700 Subject: Rename variable --- src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 83ca74ce5..75f2b0e89 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,11 +54,11 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { List positions = new LinkedList<>(); for (int i = 0; i < result.size(); i++) { JsonObject message = result.getJsonObject(i); - JsonString ident = message.getJsonString("ident"); - if (ident == null) { + JsonString identifier = message.getJsonString("ident"); + if (identifier == null) { continue; } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ident.getString()); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, identifier.getString()); if (deviceSession == null) { continue; } -- cgit v1.2.3 From 8d41fb57d1c753433654569d828345592f2fab10 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Apr 2022 17:50:10 -0700 Subject: Flespi add driver behavior --- src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 75f2b0e89..281a8a84f 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -228,6 +228,15 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_BONNET); } return true; + case "custom.wln_accel_max": + position.set("maxAcceleration", ((JsonNumber) value).doubleValue()); + return true; + case "custom.wln_brk_max": + position.set("maxBraking", ((JsonNumber) value).doubleValue()); + return true; + case "custom.wln_crn_max": + position.set("maxCornering", ((JsonNumber) value).doubleValue()); + return true; default: return false; } -- cgit v1.2.3 From a0fbcdafceafd2f00c521627a03bd108bc6f01e8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Apr 2022 18:50:39 -0700 Subject: Add documentation references --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 50 +++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index feacc1ae8..7436ff9fd 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -75,15 +75,15 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_LBS_EXTEND = 0x18; public static final int MSG_LBS_STATUS = 0x19; public static final int MSG_GPS_PHONE = 0x1A; - public static final int MSG_GPS_LBS_EXTEND = 0x1E; - public static final int MSG_HEARTBEAT = 0x23; - public static final int MSG_ADDRESS_REQUEST = 0x2A; - public static final int MSG_ADDRESS_RESPONSE = 0x97; - public static final int MSG_GPS_LBS_5 = 0x31; - public static final int MSG_GPS_LBS_STATUS_4 = 0x32; - public static final int MSG_WIFI_5 = 0x33; - public static final int MSG_AZ735_GPS = 0x32; // only extended - public static final int MSG_AZ735_ALARM = 0x33; // only extended + public static final int MSG_GPS_LBS_EXTEND = 0x1E; // JI09 + public static final int MSG_HEARTBEAT = 0x23; // GK310 + public static final int MSG_ADDRESS_REQUEST = 0x2A; // GK310 + public static final int MSG_ADDRESS_RESPONSE = 0x97; // GK310 + public static final int MSG_GPS_LBS_5 = 0x31; // AZ735 + public static final int MSG_GPS_LBS_STATUS_4 = 0x32; // AZ735 + public static final int MSG_WIFI_5 = 0x33; // AZ735 + public static final int MSG_AZ735_GPS = 0x32; // AZ735 / only extended + public static final int MSG_AZ735_ALARM = 0x33; // AZ735 / only extended public static final int MSG_X1_GPS = 0x34; public static final int MSG_X1_PHOTO_INFO = 0x35; public static final int MSG_X1_PHOTO_DATA = 0x36; @@ -93,25 +93,25 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { 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_TIME_REQUEST = 0x8A; // GK310 public static final int MSG_INFO = 0x94; public static final int MSG_SERIAL = 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; - public static final int MSG_WIFI_3 = 0xA2; - public static final int MSG_FENCE_SINGLE = 0xA3; - public static final int MSG_FENCE_MULTI = 0xA4; - public static final int MSG_LBS_ALARM = 0xA5; - public static final int MSG_LBS_ADDRESS = 0xA7; - public static final int MSG_OBD = 0x8C; - public static final int MSG_DTC = 0x65; - public static final int MSG_PID = 0x66; - public static final int MSG_BMS = 0x20; - 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; + public static final int MSG_GPS_2 = 0xA0; // GK310 + public static final int MSG_LBS_2 = 0xA1; // GK310 + public static final int MSG_WIFI_3 = 0xA2; // GK310 + public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 + public static final int MSG_FENCE_MULTI = 0xA4; // GK310 + public static final int MSG_LBS_ALARM = 0xA5; // GK310 + public static final int MSG_LBS_ADDRESS = 0xA7; // GK310 + public static final int MSG_OBD = 0x8C; // FM08ABC + public static final int MSG_DTC = 0x65; // FM08ABC + public static final int MSG_PID = 0x66; // FM08ABC + public static final int MSG_BMS = 0x20; // WD-209 + public static final int MSG_MULTIMEDIA = 0x21; // WD-209 + public static final int MSG_BMS_2 = 0x40; // WD-209 + public static final int MSG_MULTIMEDIA_2 = 0x41; // WD-209 + public static final int MSG_ALARM = 0x95; // JC100 private enum Variant { VXT01, -- cgit v1.2.3 From 1b601f506027c9f373de68ffca7f1f7a1dec815a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Apr 2022 19:39:07 -0700 Subject: Align for readability --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 50 +++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 7436ff9fd..6be0c73ca 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -75,15 +75,15 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_LBS_EXTEND = 0x18; public static final int MSG_LBS_STATUS = 0x19; public static final int MSG_GPS_PHONE = 0x1A; - public static final int MSG_GPS_LBS_EXTEND = 0x1E; // JI09 - public static final int MSG_HEARTBEAT = 0x23; // GK310 - public static final int MSG_ADDRESS_REQUEST = 0x2A; // GK310 - public static final int MSG_ADDRESS_RESPONSE = 0x97; // GK310 - public static final int MSG_GPS_LBS_5 = 0x31; // AZ735 - public static final int MSG_GPS_LBS_STATUS_4 = 0x32; // AZ735 - public static final int MSG_WIFI_5 = 0x33; // AZ735 - public static final int MSG_AZ735_GPS = 0x32; // AZ735 / only extended - public static final int MSG_AZ735_ALARM = 0x33; // AZ735 / only extended + public static final int MSG_GPS_LBS_EXTEND = 0x1E; // JI09 + public static final int MSG_HEARTBEAT = 0x23; // GK310 + public static final int MSG_ADDRESS_REQUEST = 0x2A; // GK310 + public static final int MSG_ADDRESS_RESPONSE = 0x97; // GK310 + public static final int MSG_GPS_LBS_5 = 0x31; // AZ735 + public static final int MSG_GPS_LBS_STATUS_4 = 0x32; // AZ735 + public static final int MSG_WIFI_5 = 0x33; // AZ735 + public static final int MSG_AZ735_GPS = 0x32; // AZ735 / only extended + public static final int MSG_AZ735_ALARM = 0x33; // AZ735 / only extended public static final int MSG_X1_GPS = 0x34; public static final int MSG_X1_PHOTO_INFO = 0x35; public static final int MSG_X1_PHOTO_DATA = 0x36; @@ -93,25 +93,25 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { 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; // GK310 + public static final int MSG_TIME_REQUEST = 0x8A; // GK310 public static final int MSG_INFO = 0x94; public static final int MSG_SERIAL = 0x9B; public static final int MSG_STRING_INFO = 0x21; - public static final int MSG_GPS_2 = 0xA0; // GK310 - public static final int MSG_LBS_2 = 0xA1; // GK310 - public static final int MSG_WIFI_3 = 0xA2; // GK310 - public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 - public static final int MSG_FENCE_MULTI = 0xA4; // GK310 - public static final int MSG_LBS_ALARM = 0xA5; // GK310 - public static final int MSG_LBS_ADDRESS = 0xA7; // GK310 - public static final int MSG_OBD = 0x8C; // FM08ABC - public static final int MSG_DTC = 0x65; // FM08ABC - public static final int MSG_PID = 0x66; // FM08ABC - public static final int MSG_BMS = 0x20; // WD-209 - public static final int MSG_MULTIMEDIA = 0x21; // WD-209 - public static final int MSG_BMS_2 = 0x40; // WD-209 - public static final int MSG_MULTIMEDIA_2 = 0x41; // WD-209 - public static final int MSG_ALARM = 0x95; // JC100 + public static final int MSG_GPS_2 = 0xA0; // GK310 + public static final int MSG_LBS_2 = 0xA1; // GK310 + public static final int MSG_WIFI_3 = 0xA2; // GK310 + public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 + public static final int MSG_FENCE_MULTI = 0xA4; // GK310 + public static final int MSG_LBS_ALARM = 0xA5; // GK310 + public static final int MSG_LBS_ADDRESS = 0xA7; // GK310 + public static final int MSG_OBD = 0x8C; // FM08ABC + public static final int MSG_DTC = 0x65; // FM08ABC + public static final int MSG_PID = 0x66; // FM08ABC + public static final int MSG_BMS = 0x20; // WD-209 + public static final int MSG_MULTIMEDIA = 0x21; // WD-209 + public static final int MSG_BMS_2 = 0x40; // WD-209 + public static final int MSG_MULTIMEDIA_2 = 0x41; // WD-209 + public static final int MSG_ALARM = 0x95; // JC100 private enum Variant { VXT01, -- cgit v1.2.3 From 91612195f286a538fb81291cb5604b329c015d64 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 22 Apr 2022 18:03:19 -0700 Subject: Support Meitrack extension parameters --- .../org/traccar/protocol/MeitrackProtocolDecoder.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index a9cc1de3a..013e297c0 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -404,7 +404,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { int paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { case 0x01: position.set(Position.KEY_EVENT, buf.readUnsignedByte()); @@ -430,6 +431,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case 0x9D: position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); break; + case 0xFE69: + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + break; default: buf.readUnsignedByte(); break; @@ -438,7 +442,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { case 0x08: position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); @@ -491,7 +496,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - int id = buf.readUnsignedByte(); + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { case 0x02: position.setLatitude(buf.readIntLE() * 0.000001); @@ -523,7 +529,11 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - buf.readUnsignedByte(); // id + if (buf.getUnsignedByte(buf.readerIndex()) == 0xFE) { + buf.readUnsignedShort(); // extension id + } else { + buf.readUnsignedByte(); // id + } buf.skipBytes(buf.readUnsignedByte()); // value } -- cgit v1.2.3 From bf34c777de7b8b2d87f173bda03833989b848ecf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Apr 2022 11:00:42 -0700 Subject: Flatten GT06 decoding methods --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 716 ++++++++++----------- 1 file changed, 326 insertions(+), 390 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 6be0c73ca..325527f06 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -120,6 +120,32 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { private Variant variant; + private static final Pattern PATTERN_FUEL = new PatternBuilder() + .text("!AIOIL,") + .number("d+,") // device address + .number("d+.d+,") // output value + .number("(d+.d+),") // temperature + .expression("[^,]+,") // version + .number("dd") // back wave + .number("d") // software status code + .number("d,") // hardware status code + .number("(d+.d+),") // measured value + .expression("[01],") // movement status + .number("d+,") // excited wave times + .number("xx") // checksum + .compile(); + + private static final Pattern PATTERN_LOCATION = new PatternBuilder() + .text("Current position!") + .number("Lat:([NS])(d+.d+),") // latitude + .number("Lon:([EW])(d+.d+),") // longitude + .text("Course:").number("(d+.d+),") // course + .text("Speed:").number("(d+.d+),") // speed + .text("DateTime:") + .number("(dddd)-(dd)-(dd) +") // date + .number("(dd):(dd):(dd)") // time + .compile(); + private static boolean isSupported(int type) { return hasGps(type) || hasLbs(type) || hasStatus(type); } @@ -318,7 +344,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private boolean decodeStatus(Position position, ByteBuf buf, boolean batteryLevel) { + private void decodeStatus(Position position, ByteBuf buf, boolean batteryLevel) { int status = buf.readUnsignedByte(); @@ -360,8 +386,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); } position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - - return true; } private String decodeAlarm(short value) { @@ -404,72 +428,20 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - private static final Pattern PATTERN_FUEL = new PatternBuilder() - .text("!AIOIL,") - .number("d+,") // device address - .number("d+.d+,") // output value - .number("(d+.d+),") // temperature - .expression("[^,]+,") // version - .number("dd") // back wave - .number("d") // software status code - .number("d,") // hardware status code - .number("(d+.d+),") // measured value - .expression("[01],") // movement status - .number("d+,") // excited wave times - .number("xx") // checksum - .compile(); - - private Position decodeFuelData(Position position, String sentence) { - Parser parser = new Parser(PATTERN_FUEL, sentence); - if (!parser.matches()) { - return null; - } - - position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0)); - position.set(Position.KEY_FUEL_LEVEL, parser.nextDouble(0)); - - return position; - } - - private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .text("Current position!") - .number("Lat:([NS])(d+.d+),") // latitude - .number("Lon:([EW])(d+.d+),") // longitude - .text("Course:").number("(d+.d+),") // course - .text("Speed:").number("(d+.d+),") // speed - .text("DateTime:") - .number("(dddd)-(dd)-(dd) +") // date - .number("(dd):(dd):(dd)") // time - .compile(); - - private Position decodeLocationString(Position position, String sentence) { - Parser parser = new Parser(PATTERN_LOCATION, sentence); - if (!parser.matches()) { - return null; - } - - position.setValid(true); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); - position.setCourse(parser.nextDouble()); - position.setSpeed(parser.nextDouble()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS)); - - return position; - } - private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { int length = buf.readUnsignedByte(); int dataLength = length - 5; int type = buf.readUnsignedByte(); + Position position = new Position(getProtocolName()); DeviceSession deviceSession = null; if (type != MSG_LOGIN) { deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; } + position.setDeviceId(deviceSession.getDeviceId()); if (deviceSession.getTimeZone() == null) { deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); } @@ -507,10 +479,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); } - } else if (type == MSG_HEARTBEAT) { + return null; - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + } else if (type == MSG_HEARTBEAT) { getLastLocation(position, null); @@ -539,6 +510,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { content.writeBytes(response.getBytes(StandardCharsets.US_ASCII)); sendResponse(channel, true, MSG_ADDRESS_RESPONSE, 0, content); + return null; + } else if (type == MSG_TIME_REQUEST) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); @@ -551,40 +524,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { content.writeByte(calendar.get(Calendar.SECOND)); sendResponse(channel, false, MSG_TIME_REQUEST, 0, content); - } else if (type == MSG_X1_GPS || type == MSG_X1_PHOTO_INFO) { - - return decodeX1(channel, buf, deviceSession, type); - - } else if (type == MSG_WIFI || type == MSG_WIFI_2 || type == MSG_WIFI_4) { - - return decodeWifi(channel, buf, deviceSession, type); - - } else if (type == MSG_INFO) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.set(Position.KEY_POWER, buf.readShort() * 0.01); - - return position; - - } else { - - return decodeBasicOther(channel, buf, deviceSession, type, dataLength); - - } - - return null; - } - - private Object decodeX1(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { - - if (type == MSG_X1_GPS) { + return null; - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + } else if (type == MSG_X1_GPS) { buf.readUnsignedInt(); // data and alarm @@ -632,84 +574,79 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { photos.put(pictureId, photo); sendPhotoRequest(channel, pictureId); - } - - return null; - } + return null; - private Object decodeWifi(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { + } else if (type == MSG_WIFI || type == MSG_WIFI_2 || type == MSG_WIFI_4) { - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + ByteBuf time = buf.readSlice(6); + DateBuilder dateBuilder = new DateBuilder() + .setYear(BcdUtil.readInteger(time, 2)) + .setMonth(BcdUtil.readInteger(time, 2)) + .setDay(BcdUtil.readInteger(time, 2)) + .setHour(BcdUtil.readInteger(time, 2)) + .setMinute(BcdUtil.readInteger(time, 2)) + .setSecond(BcdUtil.readInteger(time, 2)); + getLastLocation(position, dateBuilder.getDate()); - ByteBuf time = buf.readSlice(6); - DateBuilder dateBuilder = new DateBuilder() - .setYear(BcdUtil.readInteger(time, 2)) - .setMonth(BcdUtil.readInteger(time, 2)) - .setDay(BcdUtil.readInteger(time, 2)) - .setHour(BcdUtil.readInteger(time, 2)) - .setMinute(BcdUtil.readInteger(time, 2)) - .setSecond(BcdUtil.readInteger(time, 2)); - getLastLocation(position, dateBuilder.getDate()); - - Network network = new Network(); - - int wifiCount; - if (type == MSG_WIFI_4) { - wifiCount = buf.readUnsignedByte(); - } else { - wifiCount = buf.getUnsignedByte(2); - } + Network network = new Network(); - for (int i = 0; i < wifiCount; i++) { + int wifiCount; if (type == MSG_WIFI_4) { - buf.skipBytes(2); + wifiCount = buf.readUnsignedByte(); + } else { + wifiCount = buf.getUnsignedByte(2); } - WifiAccessPoint wifiAccessPoint = new WifiAccessPoint(); - wifiAccessPoint.setMacAddress(String.format("%02x:%02x:%02x:%02x:%02x:%02x", - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), - buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())); - if (type != MSG_WIFI_4) { - wifiAccessPoint.setSignalStrength((int) buf.readUnsignedByte()); + + for (int i = 0; i < wifiCount; i++) { + if (type == MSG_WIFI_4) { + buf.skipBytes(2); + } + WifiAccessPoint wifiAccessPoint = new WifiAccessPoint(); + wifiAccessPoint.setMacAddress(String.format("%02x:%02x:%02x:%02x:%02x:%02x", + buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte(), + buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())); + if (type != MSG_WIFI_4) { + wifiAccessPoint.setSignalStrength((int) buf.readUnsignedByte()); + } + network.addWifiAccessPoint(wifiAccessPoint); } - network.addWifiAccessPoint(wifiAccessPoint); - } - if (type != MSG_WIFI_4) { + if (type != MSG_WIFI_4) { - int cellCount = buf.readUnsignedByte(); - int mcc = buf.readUnsignedShort(); - int mnc = buf.readUnsignedByte(); - for (int i = 0; i < cellCount; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); - } + int cellCount = buf.readUnsignedByte(); + int mcc = buf.readUnsignedShort(); + int mnc = buf.readUnsignedByte(); + for (int i = 0; i < cellCount; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedByte())); + } + + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeShort(0x7878); + response.writeByte(0); + response.writeByte(type); + response.writeBytes(time.resetReaderIndex()); + response.writeByte('\r'); + response.writeByte('\n'); + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } - if (channel != null) { - ByteBuf response = Unpooled.buffer(); - response.writeShort(0x7878); - response.writeByte(0); - response.writeByte(type); - response.writeBytes(time.resetReaderIndex()); - response.writeByte('\r'); - response.writeByte('\n'); - channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } - } + position.setNetwork(network); - position.setNetwork(network); + return position; - return position; - } + } else if (type == MSG_INFO) { - private Object decodeBasicOther( - Channel channel, ByteBuf buf, DeviceSession deviceSession, int type, int dataLength) { + getLastLocation(position, null); - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_POWER, buf.readShort() * 0.01); - if (type == MSG_LBS_STATUS && dataLength >= 18) { + return position; + + } else if (type == MSG_LBS_STATUS && dataLength >= 18) { return null; // space10x multi-lbs message @@ -809,15 +746,117 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_STATUS && buf.readableBytes() == 22) { + + getLastLocation(position, null); + + buf.readUnsignedByte(); // information content + buf.readUnsignedShort(); // satellites + buf.readUnsignedByte(); // alarm + buf.readUnsignedByte(); // language + + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + + buf.readUnsignedByte(); // working mode + buf.readUnsignedShort(); // working voltage + buf.readUnsignedByte(); // reserved + buf.readUnsignedShort(); // working times + buf.readUnsignedShort(); // working time + + int value = buf.readUnsignedShort(); + double temperature = BitUtil.to(value, 15) * 0.1; + position.set(Position.PREFIX_TEMP + 1, BitUtil.check(value, 15) ? temperature : -temperature); + } else if (isSupported(type)) { - if (type == MSG_STATUS && buf.readableBytes() == 22) { - decodeHeartbeat(buf, position); + if (hasGps(type)) { + decodeGps(position, buf, false, deviceSession.getTimeZone()); } else { - decodeBasicUniversal(buf, deviceSession, type, position); + getLastLocation(position, null); + } + + if (hasLbs(type)) { + decodeLbs(position, buf, type, hasStatus(type)); + } + + if (hasStatus(type)) { + decodeStatus(position, buf, true); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + } + + if (type == MSG_GPS_LBS_1) { + if (buf.readableBytes() > 75 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); + buf.readUnsignedByte(); // alarm + buf.readUnsignedByte(); // swiped + position.set("driverLicense", data.trim()); + } else if (buf.readableBytes() == 8) { + int mask = buf.readUnsignedShort(); + position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); + position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); + if (BitUtil.check(mask, 8 + 4)) { + int value = BitUtil.to(mask, 8 + 1); + if (BitUtil.check(mask, 8 + 1)) { + value = -value; + } + position.set(Position.PREFIX_TEMP + 1, value); + } else { + int value = BitUtil.to(mask, 8 + 2); + if (BitUtil.check(mask, 8 + 5)) { + position.set(Position.PREFIX_ADC + 1, value); + } else { + position.set(Position.PREFIX_ADC + 1, value * 0.1); + } + } + } else if (buf.readableBytes() == 11) { + decodeStatus(position, buf, false); + buf.readUnsignedByte(); // alarm extension + } else if (buf.readableBytes() == 18) { + decodeStatus(position, buf, false); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + position.set("oil", buf.readUnsignedShort()); + int temperature = buf.readUnsignedByte(); + if (BitUtil.check(temperature, 7)) { + temperature = -BitUtil.to(temperature, 7); + } + position.set(Position.PREFIX_TEMP + 1, temperature); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 10); + } + } + + if ((type == MSG_GPS_LBS_2 || type == MSG_GPS_LBS_3 || type == MSG_GPS_LBS_4) + && buf.readableBytes() >= 3 + 6) { + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason + position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); + } + + if (type == MSG_GPS_LBS_3) { + int module = buf.readUnsignedShort(); + int subLength = buf.readUnsignedByte(); + switch (module) { + case 0x0027: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + break; + case 0x002E: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + break; + case 0x003B: + position.setAccuracy(buf.readUnsignedShort() * 0.01); + break; + default: + buf.skipBytes(subLength); + break; + } + } + + if (buf.readableBytes() == 4 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); } } else if (type == MSG_ALARM) { + boolean extendedAlarm = dataLength > 7; if (extendedAlarm) { decodeGps(position, buf, false, false, false, deviceSession.getTimeZone()); @@ -854,6 +893,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); break; } + } else { if (dataLength > 0) { @@ -879,117 +919,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } - private void decodeHeartbeat(ByteBuf buf, Position position) { - - getLastLocation(position, null); - - buf.readUnsignedByte(); // information content - buf.readUnsignedShort(); // satellites - buf.readUnsignedByte(); // alarm - buf.readUnsignedByte(); // language - - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - - buf.readUnsignedByte(); // working mode - buf.readUnsignedShort(); // working voltage - buf.readUnsignedByte(); // reserved - buf.readUnsignedShort(); // working times - buf.readUnsignedShort(); // working time - - int value = buf.readUnsignedShort(); - double temperature = BitUtil.to(value, 15) * 0.1; - position.set(Position.PREFIX_TEMP + 1, BitUtil.check(value, 15) ? temperature : -temperature); - - } - - private void decodeBasicUniversal(ByteBuf buf, DeviceSession deviceSession, int type, Position position) { - - if (hasGps(type)) { - decodeGps(position, buf, false, deviceSession.getTimeZone()); - } else { - getLastLocation(position, null); - } - - if (hasLbs(type)) { - decodeLbs(position, buf, type, hasStatus(type)); - } - - if (hasStatus(type)) { - decodeStatus(position, buf, true); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - } - - if (type == MSG_GPS_LBS_1) { - if (buf.readableBytes() > 75 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); - buf.readUnsignedByte(); // alarm - buf.readUnsignedByte(); // swiped - position.set("driverLicense", data.trim()); - } else if (buf.readableBytes() == 8) { - int mask = buf.readUnsignedShort(); - position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); - position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); - if (BitUtil.check(mask, 8 + 4)) { - int value = BitUtil.to(mask, 8 + 1); - if (BitUtil.check(mask, 8 + 1)) { - value = -value; - } - position.set(Position.PREFIX_TEMP + 1, value); - } else { - int value = BitUtil.to(mask, 8 + 2); - if (BitUtil.check(mask, 8 + 5)) { - position.set(Position.PREFIX_ADC + 1, value); - } else { - position.set(Position.PREFIX_ADC + 1, value * 0.1); - } - } - } else if (buf.readableBytes() == 11) { - decodeStatus(position, buf, false); - buf.readUnsignedByte(); // alarm extension - } else if (buf.readableBytes() == 18) { - decodeStatus(position, buf, false); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - position.set("oil", buf.readUnsignedShort()); - int temperature = buf.readUnsignedByte(); - if (BitUtil.check(temperature, 7)) { - temperature = -BitUtil.to(temperature, 7); - } - position.set(Position.PREFIX_TEMP + 1, temperature); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 10); - } - } - - if ((type == MSG_GPS_LBS_2 || type == MSG_GPS_LBS_3 || type == MSG_GPS_LBS_4) && buf.readableBytes() >= 3 + 6) { - position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason - position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); - } - - if (type == MSG_GPS_LBS_3) { - int module = buf.readUnsignedShort(); - int length = buf.readUnsignedByte(); - switch (module) { - case 0x0027: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - break; - case 0x002E: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - break; - case 0x003B: - position.setAccuracy(buf.readUnsignedShort() * 0.01); - break; - default: - buf.skipBytes(length); - break; - } - } - - if (buf.readableBytes() == 4 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } - } - private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); @@ -1017,7 +946,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { data = buf.readSlice(buf.readableBytes() - 6).toString(StandardCharsets.UTF_16BE); } - if (decodeLocationString(position, data) == null) { + Parser parser = new Parser(PATTERN_LOCATION, data); + + if (parser.matches()) { + position.setValid(true); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setCourse(parser.nextDouble()); + position.setSpeed(parser.nextDouble()); + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS)); + } else { getLastLocation(position, null); position.set(Position.KEY_RESULT, data); } @@ -1031,31 +969,50 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); if (subType == 0x00) { + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.01); return position; + } else if (subType == 0x05) { + int flags = buf.readUnsignedByte(); position.set(Position.KEY_DOOR, BitUtil.check(flags, 0)); position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); return position; + } else if (subType == 0x0a) { + buf.skipBytes(8); // imei buf.skipBytes(8); // imsi position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10)).replaceAll("f", "")); return position; + } else if (subType == 0x0d) { + if (buf.getByte(buf.readerIndex()) != '!') { buf.skipBytes(6); } - return decodeFuelData(position, buf.toString( + + Parser parser = new Parser(PATTERN_FUEL, buf.toString( buf.readerIndex(), buf.readableBytes() - 4 - 2, StandardCharsets.US_ASCII)); + if (!parser.matches()) { + return null; + } + + position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0)); + position.set(Position.KEY_FUEL_LEVEL, parser.nextDouble(0)); + + return position; + } else if (subType == 0x1b) { + buf.readUnsignedByte(); // header buf.readUnsignedByte(); // type position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(4))); buf.readUnsignedByte(); // checksum buf.readUnsignedByte(); // footer return position; + } } else if (type == MSG_X1_PHOTO_DATA) { @@ -1170,132 +1127,111 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_GPS_MODULAR) { - return decodeExtendedModular(channel, buf, deviceSession); - - } else { - - return decodeExtendedOther(channel, buf, deviceSession, type); - - } - - return null; - } - - private Object decodeExtendedModular(Channel channel, ByteBuf buf, DeviceSession deviceSession) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - while (buf.readableBytes() > 6) { - int moduleType = buf.readUnsignedShort(); - int moduleLength = buf.readUnsignedShort(); + while (buf.readableBytes() > 6) { + int moduleType = buf.readUnsignedShort(); + int moduleLength = buf.readUnsignedShort(); - switch (moduleType) { - case 0x03: - position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10))); - break; - case 0x09: - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case 0x0a: - position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); - break; - case 0x11: - CellTower cellTower = CellTower.from( - buf.readUnsignedShort(), - buf.readUnsignedShort(), - buf.readUnsignedShort(), - buf.readUnsignedMedium(), - buf.readUnsignedByte()); - if (cellTower.getCellId() > 0) { - position.setNetwork(new Network(cellTower)); - } - break; - 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; - case 0x34: - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - buf.readUnsignedIntLE(); // time - buf.skipBytes(buf.readUnsignedByte()); // content - break; - default: - buf.skipBytes(moduleLength); - break; + switch (moduleType) { + case 0x03: + position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10))); + break; + case 0x09: + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + break; + case 0x0a: + position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); + break; + case 0x11: + CellTower cellTower = CellTower.from( + buf.readUnsignedShort(), + buf.readUnsignedShort(), + buf.readUnsignedShort(), + buf.readUnsignedMedium(), + buf.readUnsignedByte()); + if (cellTower.getCellId() > 0) { + position.setNetwork(new Network(cellTower)); + } + break; + 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; + case 0x34: + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + buf.readUnsignedIntLE(); // time + buf.skipBytes(buf.readUnsignedByte()); // content + break; + default: + buf.skipBytes(moduleLength); + break; + } } - } - if (position.getFixTime() == null) { - getLastLocation(position, null); - } - - sendResponse(channel, false, MSG_GPS_MODULAR, buf.readUnsignedShort(), null); - - return position; - } + if (position.getFixTime() == null) { + getLastLocation(position, null); + } - private Object decodeExtendedOther(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) { + sendResponse(channel, false, MSG_GPS_MODULAR, buf.readUnsignedShort(), null); - Position position = null; + return position; - if (type == MSG_MULTIMEDIA || type == MSG_MULTIMEDIA_2) { + } else if (type == MSG_MULTIMEDIA || type == MSG_MULTIMEDIA_2) { buf.skipBytes(8); // serial number long timestamp = buf.readUnsignedInt() * 1000; -- cgit v1.2.3 From c10e8132c4dc4a78b3440725516ffaaec6834406 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Apr 2022 13:27:51 -0700 Subject: Decode GT06 variants --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 52 +++++++++++++--------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 325527f06..89931f614 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1,5 +1,5 @@ /* -Supp * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -107,14 +107,17 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_OBD = 0x8C; // FM08ABC public static final int MSG_DTC = 0x65; // FM08ABC public static final int MSG_PID = 0x66; // FM08ABC - public static final int MSG_BMS = 0x20; // WD-209 - public static final int MSG_MULTIMEDIA = 0x21; // WD-209 - public static final int MSG_BMS_2 = 0x40; // WD-209 - public static final int MSG_MULTIMEDIA_2 = 0x41; // WD-209 + public static final int MSG_BMS = 0x40; // WD-209 + public static final int MSG_MULTIMEDIA = 0x41; // WD-209 public static final int MSG_ALARM = 0x95; // JC100 private enum Variant { VXT01, + WANWAY_S20, + GT06E_CARD, + BENWAY, + S5, + SPACE10X, STANDARD, } @@ -472,7 +475,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { deviceSession.setTimeZone(timeZone); } } - } if (deviceSession != null) { @@ -646,10 +648,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type == MSG_LBS_STATUS && dataLength >= 18) { - - return null; // space10x multi-lbs message - } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_MULTIPLE_3 || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI || type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5) { @@ -662,9 +660,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, dateBuilder.getDate()); - boolean hasCellCount = type == MSG_LBS_MULTIPLE_3 && dataLength == 44; - - if (hasCellCount) { + if (variant == Variant.WANWAY_S20) { buf.readUnsignedByte(); // ta } @@ -672,7 +668,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int mnc = BitUtil.check(mcc, 15) ? buf.readUnsignedShort() : buf.readUnsignedByte(); Network network = new Network(); - int cellCount = hasCellCount ? buf.readUnsignedByte() : type == MSG_WIFI_5 ? 6 : 7; + int cellCount = variant == Variant.WANWAY_S20 ? buf.readUnsignedByte() : type == MSG_WIFI_5 ? 6 : 7; for (int i = 0; i < cellCount; i++) { int lac = longFormat ? buf.readInt() : buf.readUnsignedShort(); int cid = longFormat ? (int) buf.readLong() : buf.readUnsignedMedium(); @@ -682,7 +678,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - if (!hasCellCount) { + if (variant != Variant.WANWAY_S20) { buf.readUnsignedByte(); // ta } @@ -714,7 +710,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } - } else if (type == MSG_BMS || type == MSG_BMS_2) { + } else if (type == MSG_BMS) { buf.skipBytes(8); // serial number @@ -769,6 +765,10 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (isSupported(type)) { + if (type == MSG_LBS_STATUS && variant == Variant.SPACE10X) { + return null; // multi-lbs message + } + if (hasGps(type)) { decodeGps(position, buf, false, deviceSession.getTimeZone()); } else { @@ -785,13 +785,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (type == MSG_GPS_LBS_1) { - if (buf.readableBytes() > 75 + 6) { + if (variant == Variant.GT06E_CARD) { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); buf.readUnsignedByte(); // alarm buf.readUnsignedByte(); // swiped position.set("driverLicense", data.trim()); - } else if (buf.readableBytes() == 8) { + } else if (variant == Variant.BENWAY) { int mask = buf.readUnsignedShort(); position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7)); position.set(Position.PREFIX_IN + 2, BitUtil.check(mask, 8 + 6)); @@ -809,10 +809,10 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + 1, value * 0.1); } } - } else if (buf.readableBytes() == 11) { + } else if (variant == Variant.VXT01) { decodeStatus(position, buf, false); buf.readUnsignedByte(); // alarm extension - } else if (buf.readableBytes() == 18) { + } else if (variant == Variant.S5) { decodeStatus(position, buf, false); position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("oil", buf.readUnsignedShort()); @@ -1231,7 +1231,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; - } else if (type == MSG_MULTIMEDIA || type == MSG_MULTIMEDIA_2) { + } else if (type == MSG_MULTIMEDIA) { buf.skipBytes(8); // serial number long timestamp = buf.readUnsignedInt() * 1000; @@ -1322,6 +1322,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.VXT01; } else if (header == 0x7878 && type == MSG_GPS_LBS_STATUS_1 && length == 0x24) { variant = Variant.VXT01; + } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x31) { + variant = Variant.WANWAY_S20; + } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length >= 0x71) { + variant = Variant.GT06E_CARD; + } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x21) { + variant = Variant.BENWAY; + } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x2b) { + variant = Variant.S5; + } else if (header == 0x7878 && type == MSG_LBS_STATUS && length >= 0x17) { + variant = Variant.SPACE10X; } else { variant = Variant.STANDARD; } -- cgit v1.2.3 From 94fa65d6961fc369923b11a60758b83ac7c3ecae Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 30 Apr 2022 09:30:43 -0700 Subject: Fix Envotech location --- src/main/java/org/traccar/helper/Parser.java | 5 +++++ .../traccar/protocol/EnvotechProtocolDecoder.java | 21 ++++++++++++++++----- .../protocol/EnvotechProtocolDecoderTest.java | 3 ++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/helper/Parser.java b/src/main/java/org/traccar/helper/Parser.java index 75106e2ba..22e98ded1 100644 --- a/src/main/java/org/traccar/helper/Parser.java +++ b/src/main/java/org/traccar/helper/Parser.java @@ -155,6 +155,7 @@ public class Parser { public enum CoordinateFormat { DEG_DEG, + DEG_DEG_HEM, DEG_HEM, DEG_MIN_MIN, DEG_MIN_HEM, @@ -173,6 +174,10 @@ public class Parser { case DEG_DEG: coordinate = Double.parseDouble(next() + '.' + next()); break; + case DEG_DEG_HEM: + coordinate = Double.parseDouble(next() + '.' + next()); + hemisphere = next(); + break; case DEG_HEM: coordinate = nextDouble(0); hemisphere = next(); diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java index 083d8a921..51391d4cc 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -54,8 +54,8 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { .number("(dd)(dd)(dd)") // date (ddmmyy) .number("(dd)(dd)(dd)") // time (hhmmss) .number("(d)") // fix - .number("(dd)(dd)(d+)([NS])") // latitude - .number("(ddd)(dd)(d+)([EW])") // longitude + .number("(d+)(d{5})([NS])") // latitude + .number("(d+)(d{5})([EW])") // longitude .number("(ddd)") // speed .number("(ddd)") // course .any() @@ -72,7 +72,18 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); - position.set(Position.KEY_EVENT, parser.nextHexInt()); + int event = parser.nextHexInt(); + switch (event) { + case 0x60: + position.set(Position.KEY_ALARM, Position.ALARM_LOCK); + break; + case 0x61: + position.set(Position.KEY_ALARM, Position.ALARM_UNLOCK); + break; + default: + break; + } + position.set(Position.KEY_EVENT, event); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { @@ -92,8 +103,8 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); position.setValid(parser.nextInt() > 0); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN_HEM)); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_DEG_HEM)); position.setSpeed(parser.nextInt()); position.setCourse(parser.nextInt()); diff --git a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java index 6a455975d..60c592e1e 100644 --- a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java @@ -11,7 +11,8 @@ public class EnvotechProtocolDecoderTest extends ProtocolTest { var decoder = new EnvotechProtocolDecoder(null); verifyPosition(decoder, text( - "$80SLM,02,F,AB0010,130410155921,431750216,000040,0000,,00000000,'13041015592110476673N10111459E001281*2A")); + "$80SLM,02,F,AB0010,130410155921,431750216,000040,0000,,00000000,'13041015592110476673N10111459E001281*2A"), + position("2010-04-13 15:59:21.000", true, 4.76673, 101.11459)); verifyPosition(decoder, text( "$80SLM,82,F,AB0010,130410155921,431750216,000040,0000,,00000000,'13041015592110476673N10111459E001281@B0,F,C456,038,00,M234567,,,1A2A3A4A5A6A*4E")); -- cgit v1.2.3 From 2a6e75c5d9527cb7b5b54e257fd756e717d5347a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 30 Apr 2022 18:29:37 -0700 Subject: Implement cluster broadcasting --- debug.xml | 3 + src/main/java/org/traccar/Context.java | 11 +++ src/main/java/org/traccar/Main.java | 15 ++-- src/main/java/org/traccar/MainEventHandler.java | 10 +++ .../org/traccar/broadcast/BroadcastMessage.java | 42 +++++++++ .../org/traccar/broadcast/BroadcastService.java | 100 +++++++++++++++++++++ .../java/org/traccar/broadcast/DeviceStatus.java | 52 +++++++++++ src/main/java/org/traccar/config/Keys.java | 14 +++ 8 files changed, 241 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/traccar/broadcast/BroadcastMessage.java create mode 100644 src/main/java/org/traccar/broadcast/BroadcastService.java create mode 100644 src/main/java/org/traccar/broadcast/DeviceStatus.java diff --git a/debug.xml b/debug.xml index f9515bb2b..29ece6260 100644 --- a/debug.xml +++ b/debug.xml @@ -20,4 +20,7 @@ true 6037 + + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index aeba9c4c9..c44d432b2 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr353.JSR353Module; import org.apache.velocity.app.VelocityEngine; import org.eclipse.jetty.util.URIUtil; +import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.AttributesManager; @@ -171,6 +172,12 @@ public final class Context { return scheduleManager; } + private static BroadcastService broadcastService; + + public static BroadcastService getBroadcastService() { + return broadcastService; + } + private static GeofenceManager geofenceManager; public static GeofenceManager getGeofenceManager() { @@ -335,6 +342,10 @@ public final class Context { serverManager = new ServerManager(); scheduleManager = new ScheduleManager(); + if (config.hasKey(Keys.BROADCAST_ADDRESS)) { + broadcastService = new BroadcastService(config, objectMapper); + } + if (config.hasKey(Keys.EVENT_FORWARD_URL)) { eventForwarder = new EventForwarder(); } diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 6daf72bb4..2eaf394af 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -118,13 +118,14 @@ public final class Main { List services = new LinkedList<>(); services.add(Context.getServerManager()); - if (Context.getWebServer() != null) { - services.add(Context.getWebServer()); - } + services.add(Context.getWebServer()); services.add(Context.getScheduleManager()); + services.add(Context.getBroadcastService()); for (LifecycleObject service : services) { - service.start(); + if (service != null) { + service.start(); + } } Thread.setDefaultUncaughtExceptionHandler((t, e) -> LOGGER.error("Thread exception", e)); @@ -134,7 +135,9 @@ public final class Main { Collections.reverse(services); for (LifecycleObject service : services) { - service.stop(); + if (service != null) { + service.stop(); + } } })); } catch (Exception e) { diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index a3f6f4105..0e60ac06d 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -23,12 +23,14 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.broadcast.BroadcastMessage; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.model.Position; import org.traccar.storage.StorageException; +import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; @@ -61,6 +63,14 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { LOGGER.warn("Failed to update device", error); } + BroadcastMessage message = new BroadcastMessage(); + message.setPosition(position); + try { + Context.getBroadcastService().sendMessage(message); + } catch (IOException e) { + e.printStackTrace(); + } + String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); StringBuilder builder = new StringBuilder(); diff --git a/src/main/java/org/traccar/broadcast/BroadcastMessage.java b/src/main/java/org/traccar/broadcast/BroadcastMessage.java new file mode 100644 index 000000000..6b103f373 --- /dev/null +++ b/src/main/java/org/traccar/broadcast/BroadcastMessage.java @@ -0,0 +1,42 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.broadcast; + +import org.traccar.model.Position; + +public class BroadcastMessage { + + private DeviceStatus deviceStatus; + + public DeviceStatus getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(DeviceStatus deviceStatus) { + this.deviceStatus = deviceStatus; + } + + private Position position; + + public Position getPosition() { + return position; + } + + public void setPosition(Position position) { + this.position = position; + } + +} diff --git a/src/main/java/org/traccar/broadcast/BroadcastService.java b/src/main/java/org/traccar/broadcast/BroadcastService.java new file mode 100644 index 000000000..b17857fcd --- /dev/null +++ b/src/main/java/org/traccar/broadcast/BroadcastService.java @@ -0,0 +1,100 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.broadcast; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.LifecycleObject; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Inject; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class BroadcastService implements LifecycleObject { + + private static final Logger LOGGER = LoggerFactory.getLogger(BroadcastService.class); + + private final ObjectMapper objectMapper; + + private final InetAddress address; + private final int port; + + private DatagramSocket publisherSocket; + + private final ExecutorService service = Executors.newSingleThreadExecutor(); + private final byte[] receiverBuffer = new byte[4096]; + + @Inject + public BroadcastService(Config config, ObjectMapper objectMapper) throws IOException { + this.objectMapper = objectMapper; + address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); + port = config.getInteger(Keys.BROADCAST_PORT); + } + + public void sendMessage(BroadcastMessage message) throws IOException { + byte[] buffer = objectMapper.writeValueAsString(message).getBytes(StandardCharsets.UTF_8); + DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port); + publisherSocket.send(packet); + } + + private void handleMessage(BroadcastMessage message) { + if (message.getDeviceStatus() != null) { + LOGGER.info("Broadcast received device {}", message.getDeviceStatus().getDeviceId()); + } else if (message.getPosition() != null) { + LOGGER.info("Broadcast received position {}", message.getPosition().getDeviceId()); + } + } + + @Override + public void start() throws IOException { + service.submit(receiver); + publisherSocket = new DatagramSocket(); + } + + @Override + public void stop() { + publisherSocket.close(); + service.shutdown(); + } + + private final Runnable receiver = new Runnable() { + @Override + public void run() { + try (MulticastSocket socket = new MulticastSocket(port)) { + socket.joinGroup(address); + while (!service.isShutdown()) { + DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); + socket.receive(packet); + String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); + handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); + } + socket.leaveGroup(address); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }; + +} diff --git a/src/main/java/org/traccar/broadcast/DeviceStatus.java b/src/main/java/org/traccar/broadcast/DeviceStatus.java new file mode 100644 index 000000000..4f0143319 --- /dev/null +++ b/src/main/java/org/traccar/broadcast/DeviceStatus.java @@ -0,0 +1,52 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.broadcast; + +import java.util.Date; + +public class DeviceStatus { + + private long deviceId; + + public long getDeviceId() { + return deviceId; + } + + public void setDeviceId(long deviceId) { + this.deviceId = deviceId; + } + + private String status; + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + private Date lastUpdate; + + public Date getLastUpdate() { + return this.lastUpdate; + } + + public void setLastUpdate(Date lastUpdate) { + this.lastUpdate = lastUpdate; + } + +} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index ccfe4bee7..dc6bcbec9 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1309,4 +1309,18 @@ public final class Keys { Collections.singletonList(KeyType.GLOBAL), "time,position,speed,course,accuracy,result"); + /** + * Multicast address for broadcasting synchronization events. + */ + public static final ConfigKey BROADCAST_ADDRESS = new ConfigKey<>( + "broadcast.address", + Collections.singletonList(KeyType.GLOBAL)); + + /** + * Multicast port for broadcasting synchronization events. + */ + public static final ConfigKey BROADCAST_PORT = new ConfigKey<>( + "broadcast.port", + Collections.singletonList(KeyType.GLOBAL)); + } -- cgit v1.2.3 From 19869710f012cbf1a32063021d59aa2d58688e6b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 1 May 2022 16:02:11 -0700 Subject: Remove test broadcase --- src/main/java/org/traccar/MainEventHandler.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 0e60ac06d..a3f6f4105 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -23,14 +23,12 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.broadcast.BroadcastMessage; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.model.Position; import org.traccar.storage.StorageException; -import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; @@ -63,14 +61,6 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { LOGGER.warn("Failed to update device", error); } - BroadcastMessage message = new BroadcastMessage(); - message.setPosition(position); - try { - Context.getBroadcastService().sendMessage(message); - } catch (IOException e) { - e.printStackTrace(); - } - String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); StringBuilder builder = new StringBuilder(); -- cgit v1.2.3 From 9633eccdead886ed0b580707ad76cdf06df9a603 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 2 May 2022 08:22:53 -0700 Subject: Log transport layer protocol --- src/main/java/org/traccar/BaseProtocolEncoder.java | 3 ++- src/main/java/org/traccar/MainEventHandler.java | 17 +++++------- .../traccar/handler/StandardLoggingHandler.java | 8 +++--- src/main/java/org/traccar/helper/NetworkUtil.java | 31 ++++++++++++++++++++++ 4 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 src/main/java/org/traccar/helper/NetworkUtil.java diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index b6df07b98..71fa61e4e 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -21,6 +21,7 @@ import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.helper.NetworkUtil; import org.traccar.model.Command; public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter { @@ -62,7 +63,7 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter Object encodedCommand = encodeCommand(ctx.channel(), command); StringBuilder s = new StringBuilder(); - s.append("[").append(ctx.channel().id().asShortText()).append("] "); + s.append("[").append(NetworkUtil.session(ctx.channel())).append("] "); s.append("id: ").append(getUniqueId(command.getDeviceId())).append(", "); s.append("command type: ").append(command.getType()).append(" "); if (encodedCommand != null) { diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index a3f6f4105..f1f2527bc 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; +import org.traccar.helper.NetworkUtil; import org.traccar.model.Position; import org.traccar.storage.StorageException; @@ -64,7 +65,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); StringBuilder builder = new StringBuilder(); - builder.append(formatChannel(ctx.channel())).append(" "); + builder.append("[").append(NetworkUtil.session(ctx.channel())).append("] "); builder.append("id: ").append(uniqueId); for (String attribute : logAttributes) { switch (attribute) { @@ -113,20 +114,16 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { } } - private static String formatChannel(Channel channel) { - return String.format("[%s]", channel.id().asShortText()); - } - @Override public void channelActive(ChannelHandlerContext ctx) { if (!(ctx.channel() instanceof DatagramChannel)) { - LOGGER.info(formatChannel(ctx.channel()) + " connected"); + LOGGER.info("[{}] connected", NetworkUtil.session(ctx.channel())); } } @Override public void channelInactive(ChannelHandlerContext ctx) { - LOGGER.info(formatChannel(ctx.channel()) + " disconnected"); + LOGGER.info("[{}] disconnected", NetworkUtil.session(ctx.channel())); closeChannel(ctx.channel()); if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null @@ -140,14 +137,14 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { while (cause.getCause() != null && cause.getCause() != cause) { cause = cause.getCause(); } - LOGGER.warn(formatChannel(ctx.channel()) + " error", cause); + LOGGER.info("[{}] error", NetworkUtil.session(ctx.channel()), cause); closeChannel(ctx.channel()); } @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { if (evt instanceof IdleStateEvent) { - LOGGER.info(formatChannel(ctx.channel()) + " timed out"); + LOGGER.info("[{}] timed out", NetworkUtil.session(ctx.channel())); closeChannel(ctx.channel()); } } diff --git a/src/main/java/org/traccar/handler/StandardLoggingHandler.java b/src/main/java/org/traccar/handler/StandardLoggingHandler.java index 13c5f8281..84492e2a5 100644 --- a/src/main/java/org/traccar/handler/StandardLoggingHandler.java +++ b/src/main/java/org/traccar/handler/StandardLoggingHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@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 io.netty.channel.ChannelPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.NetworkMessage; +import org.traccar.helper.NetworkUtil; import java.net.InetSocketAddress; import java.net.SocketAddress; @@ -63,7 +64,7 @@ public class StandardLoggingHandler extends ChannelDuplexHandler { public void log(ChannelHandlerContext ctx, boolean downstream, SocketAddress remoteAddress, ByteBuf buf) { StringBuilder message = new StringBuilder(); - message.append("[").append(ctx.channel().id().asShortText()).append(": "); + message.append("[").append(NetworkUtil.session(ctx.channel())).append(": "); message.append(protocol); if (downstream) { message.append(" > "); @@ -76,9 +77,8 @@ public class StandardLoggingHandler extends ChannelDuplexHandler { } else { message.append("unknown"); } - message.append("]"); + message.append("] "); - message.append(" HEX: "); message.append(ByteBufUtil.hexDump(buf)); LOGGER.info(message.toString()); diff --git a/src/main/java/org/traccar/helper/NetworkUtil.java b/src/main/java/org/traccar/helper/NetworkUtil.java new file mode 100644 index 000000000..2fe3487da --- /dev/null +++ b/src/main/java/org/traccar/helper/NetworkUtil.java @@ -0,0 +1,31 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper; + +import io.netty.channel.Channel; +import io.netty.channel.socket.DatagramChannel; + +public final class NetworkUtil { + + private NetworkUtil() { + } + + public static String session(Channel channel) { + char transport = channel instanceof DatagramChannel ? 'U' : 'T'; + return transport + channel.id().asShortText(); + } + +} -- cgit v1.2.3 From 8853720199fb97d31d61cb442b5eac2d547aa8a0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 2 May 2022 08:35:18 -0700 Subject: Fix Envotech status decoding --- src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java index 51391d4cc..347063547 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -99,7 +99,7 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_INPUT, parser.nextHexInt()); position.set(Position.PREFIX_OUT, parser.nextHexInt()); position.set(Position.KEY_FUEL_LEVEL, parser.nextHexInt()); - position.set(Position.KEY_STATUS, parser.nextHexInt()); + position.set(Position.KEY_STATUS, parser.nextHexLong()); position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); position.setValid(parser.nextInt() > 0); diff --git a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java index 60c592e1e..70fb5a188 100644 --- a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class EnvotechProtocolDecoderTest extends ProtocolTest { var decoder = new EnvotechProtocolDecoder(null); + verifyPosition(decoder, text( + "$80SLM,62,000F,F015727,020522053200,611000000,000391,C080,000,80028900,85010000'02052205320110399426S03970217E000145*E0C2#")); + verifyPosition(decoder, text( "$80SLM,02,F,AB0010,130410155921,431750216,000040,0000,,00000000,'13041015592110476673N10111459E001281*2A"), position("2010-04-13 15:59:21.000", true, 4.76673, 101.11459)); -- cgit v1.2.3 From d8bb9c055a3fcc15dfc92ea8238b4c26bf71f55c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 2 May 2022 16:50:14 -0700 Subject: Configurable API sanitization --- setup/default.xml | 1 + src/main/java/org/traccar/Context.java | 4 +++- src/main/java/org/traccar/config/Keys.java | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/setup/default.xml b/setup/default.xml index 71e14f501..1f89ae3d8 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -12,6 +12,7 @@ 8082 ./web + true false true diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index c44d432b2..ee14f8a1a 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -294,7 +294,9 @@ public final class Context { } objectMapper = new ObjectMapper(); - objectMapper.registerModule(new SanitizerModule()); + if (config.getBoolean(Keys.WEB_SANITIZE)) { + objectMapper.registerModule(new SanitizerModule()); + } objectMapper.registerModule(new JSR353Module()); objectMapper.setConfig( objectMapper.getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index dc6bcbec9..f5299b90b 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -552,6 +552,14 @@ public final class Keys { "web.port", Collections.singletonList(KeyType.GLOBAL)); + /** + * Sanitize all strings returned via API. This is needed to fix XSS issues in the old web interface. New React-based + * interface doesn't require this. + */ + public static final ConfigKey WEB_SANITIZE = new ConfigKey<>( + "web.sanitize", + Collections.singletonList(KeyType.GLOBAL)); + /** * Path to the web app folder. */ -- cgit v1.2.3 From b8f0c159aa3e13e902305e4b68ad7f851696b69c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 6 May 2022 15:00:06 -0700 Subject: Add timezones API --- src/main/java/org/traccar/api/resource/ServerResource.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 2d17d5e47..f238e8905 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -34,6 +34,9 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.util.Arrays; +import java.util.Collection; +import java.util.TimeZone; @Path("server") @Produces(MediaType.APPLICATION_JSON) @@ -67,4 +70,10 @@ public class ServerResource extends BaseResource { } } + @Path("timezones") + @GET + public Collection timezones() { + return Arrays.asList(TimeZone.getAvailableIDs()); + } + } -- cgit v1.2.3 From 78a3d28440b4de89eaab79664fef512e6e869030 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 12 May 2022 17:19:32 -0700 Subject: Support Envotech IVM format --- src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java | 4 +++- src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java index 347063547..65d5e3859 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -48,7 +48,8 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { .number("(ddd),") // battery .number("(xx)") // inputs .number("(xx),") // outputs - .number("(xxx)?,") // fuel + .number("(xxx)?") // fuel + .number("(xxx)?,") // weight .number("(x{8}),") // status .expression("[^']*'") .number("(dd)(dd)(dd)") // date (ddmmyy) @@ -99,6 +100,7 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_INPUT, parser.nextHexInt()); position.set(Position.PREFIX_OUT, parser.nextHexInt()); position.set(Position.KEY_FUEL_LEVEL, parser.nextHexInt()); + position.set("weight", parser.nextHexInt()); position.set(Position.KEY_STATUS, parser.nextHexLong()); position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); diff --git a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java index 70fb5a188..0809a1e9a 100644 --- a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class EnvotechProtocolDecoderTest extends ProtocolTest { var decoder = new EnvotechProtocolDecoder(null); + verifyPosition(decoder, text( + "$80IVM,03,E002215,E002215,110422061936,672763902,126423,0180,000000,00018600,0.0000'11042206193710406325S03966094E000118*42D6#")); + verifyPosition(decoder, text( "$80SLM,62,000F,F015727,020522053200,611000000,000391,C080,000,80028900,85010000'02052205320110399426S03970217E000145*E0C2#")); -- cgit v1.2.3 From 7a0e14eda651314d7bd076c882dd872964b16832 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 12 May 2022 17:51:48 -0700 Subject: Decode Wireless Links cell data --- .../org/traccar/protocol/WliProtocolDecoder.java | 74 ++++++++++++++++++---- .../traccar/protocol/WliProtocolDecoderTest.java | 3 + 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java index 0e2a0a65e..976d4fb27 100644 --- a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,8 @@ import org.traccar.DeviceSession; import org.traccar.Protocol; 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; import java.net.SocketAddress; @@ -41,9 +43,9 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; buf.readUnsignedByte(); // header - int type = buf.readUnsignedByte(); + int clazz = buf.readUnsignedByte(); - if (type == '1') { + if (clazz == '1') { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { @@ -53,11 +55,13 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + CellTower cellTower = new CellTower(); + position.set(Position.KEY_INDEX, buf.readUnsignedShort()); buf.readUnsignedShort(); // length buf.readUnsignedShort(); // checksum - buf.readUnsignedByte(); // application message type + int type = buf.readUnsignedByte(); buf.readUnsignedByte(); // delimiter while (buf.readableBytes() > 1) { @@ -95,18 +99,56 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { String value = buf.readCharSequence( endIndex - buf.readerIndex(), StandardCharsets.US_ASCII).toString(); - switch (fieldNumber) { - case 246: - String[] values = value.split(","); - position.set(Position.KEY_POWER, Integer.parseInt(values[2]) * 0.01); - position.set(Position.KEY_BATTERY, Integer.parseInt(values[3]) * 0.01); + int networkFieldsOffset; + switch (type) { + case 0xE4: + networkFieldsOffset = 10; + break; + case 0xCB: + networkFieldsOffset = 80; break; - case 255: - position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); + case 0x1E: + networkFieldsOffset = 182; break; + case 0xC9: default: + networkFieldsOffset = 35; break; } + if (fieldNumber - networkFieldsOffset >= 0 && fieldNumber - networkFieldsOffset < 10) { + switch (fieldNumber - networkFieldsOffset) { + case 0: + cellTower.setMobileCountryCode(Integer.parseInt(value)); + break; + case 1: + cellTower.setMobileNetworkCode(Integer.parseInt(value)); + break; + case 2: + cellTower.setLocationAreaCode(Integer.parseInt(value)); + break; + case 3: + cellTower.setCellId(Long.parseLong(value)); + break; + case 4: + cellTower.setSignalStrength(Integer.parseInt(value)); + break; + default: + break; + } + } else { + switch (fieldNumber) { + case 246: + String[] values = value.split(","); + position.set(Position.KEY_POWER, Integer.parseInt(values[2]) * 0.01); + position.set(Position.KEY_BATTERY, Integer.parseInt(values[3]) * 0.01); + break; + case 255: + position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); + break; + default: + break; + } + } } @@ -114,13 +156,21 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { } + if (type == 0xE4) { + getLastLocation(position, position.getDeviceTime()); + } + + if (cellTower.getCellId() != null) { + position.setNetwork(new Network(cellTower)); + } + if (!position.getValid()) { getLastLocation(position, position.getDeviceTime()); } return position; - } else if (type == '2') { + } else if (clazz == '2') { String id = buf.toString(buf.readerIndex(), buf.readableBytes() - 1, StandardCharsets.US_ASCII); getDeviceSession(channel, remoteAddress, id.substring("wli:".length())); diff --git a/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java index 6f86a9fd9..77184f86a 100644 --- a/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class WliProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "0232776c693a30343930333332303332343103")); + verifyAttributes(decoder, binary( + "0231000101536c27e40001003400dbd20030363a34323a303000dbd30030352f30322f31390004002d3100060030000a00343235000b003031000c003130343232000d003336343733000e003239000f0037001000312c312c312c312c31302e3230322e33342e33312c36353533352c302c39392c39392c3235352c3235352c3235352c323535001100300013003000140033001500343237001600333700170031001800313038001900320031003000320030004500302c323031392f30352f30322c30363a34313a34312c323031392f30352f30322c30363a33353a303800f100342c302c332c302c2d312c2d3100f2003300f3003100f50038363634323530333137303639323400f600312c302c302c3431322c3000f70038343437373200f800302c3330302c302c302c302c302c2c2c2c2c2c302c3000f9003300fa00393100fb0032313100fc0032313000ff00313535363737393332300003")); + verifyPosition(decoder, binary( "0231000101bba758c900010034000500ff001001258fc9013e80ed00001183350101e20006003200090030000a0032000b003331000c0031000d00343438000e003530000f003100100031303800130032001b003134001c0033392c33352c32382c33382c34302c33372c33332c33382c33352c34322c33372c3335001d003130001e0038002300343235002400303100250031303432320026003336343733002700323800280037002900312c312c312c312c31302e3232352e3135312e3230342c36353533352c302c39392c39392c3235352c3235352c3235352c323535002a0030002c0030003000300032003000330031003400ff001c0214130502061b0101258fc9013e80ed000001e2000000000000004d004500302c323031392f30352f30322c30363a33333a30302c323031392f30352f30322c30363a32363a3230005a003000f100352c302c342c302c2d312c2d3100f2003300f3003100f50038363634323530333137303639323400f600312c302c302c3431322c3000f70038343437373200f80032312c31312c302c302c302c302c2c2c2c2c2c302c3000f9003300fa00393100fb0032313100fc0032313000ff00313535363737383533340003")); -- cgit v1.2.3 From bac331ebf2a67d0bdc4f96c78f0dfbeb0c4b6da6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 15 May 2022 16:58:10 -0700 Subject: Handle Startek OBD issue --- src/main/java/org/traccar/protocol/StartekProtocolDecoder.java | 4 +++- src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index c1869def2..8a7b5cec7 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -42,7 +42,6 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .number("d+,") // length .number("(d+),") // imei .expression("(.+)") // content - .number("xx") // checksum .compile(); private static final Pattern PATTERN_POSITION = new PatternBuilder() @@ -123,6 +122,9 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { } String content = parser.next(); + if (content.charAt(content.length() - 2 - 1) != '|') { + content = content.substring(0, content.length() - 2); + } if (content.length() < 100) { Position position = new Position(getProtocolName()); diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index 6c2d39940..cea079156 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -11,8 +11,9 @@ public class StartekProtocolDecoderTest extends ProtocolTest { var decoder = new StartekProtocolDecoder(null); - verifyPosition(decoder, text( - "&&R187,860294046453690,000,0,,220105160656,A,22.994986,72.499711,15,0.9,2,222,55,121135784,404|98|147B|0000376A,24,0000001F,02,00,052E|01A3|0000|0000,1,010000|020000,,853|6|10|105|73|41|125|34|52")); + verifyAttribute(decoder, text( + "&&R187,860294046453690,000,0,,220105160656,A,22.994986,72.499711,15,0.9,2,222,55,121135784,404|98|147B|0000376A,24,0000001F,02,00,052E|01A3|0000|0000,1,010000|020000,,853|6|10|105|73|41|125|34|52"), + Position.KEY_FUEL_LEVEL, 52); verifyPosition(decoder, text( "&&o142,860262050066062,000,27,,211111070826,V,28.653435,-106.077455,0,0.0,0,151,1412,918,0|0|4708|01402D19,6,0000001A,02,00,04C0|016C|0000|0000,1,,,BB")); -- cgit v1.2.3 From 823795e40bf9b029a5c6c80fe58744244d24a5c7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 16 May 2022 17:29:52 -0700 Subject: Add Concox/Jimi VL502 transparent data --- .../traccar/protocol/HuabaoProtocolDecoder.java | 157 +++++++++++++++++++-- .../protocol/HuabaoProtocolDecoderTest.java | 3 + 2 files changed, 145 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index b0ad9a229..c280ee9b2 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -64,6 +64,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_TIME_SYNC_REQUEST = 0x0109; public static final int MSG_TIME_SYNC_RESPONSE = 0x8109; public static final int MSG_PHOTO = 0x8888; + public static final int MSG_TRANSPARENT = 0x0900; public static final int RESULT_SUCCESS = 0; @@ -148,6 +149,17 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return BitUtil.check(value, 15) ? -BitUtil.to(value, 15) : BitUtil.to(value, 15); } + private Date readDate(ByteBuf buf, TimeZone timeZone) { + DateBuilder dateBuilder = new DateBuilder(timeZone) + .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)); + return dateBuilder.getDate(); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -267,6 +279,10 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_TRANSPARENT) { + + return decodeTransparent(deviceSession, buf); + } return null; @@ -354,12 +370,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } } - private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt())); + private void decodeCoordinates(Position position, ByteBuf buf) { int status = buf.readInt(); @@ -382,19 +393,21 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } else { position.setLongitude(lon); } + } + + private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt())); + + decodeCoordinates(position, buf); position.setAltitude(buf.readShort()); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort()); - - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) - .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)); - position.setTime(dateBuilder.getDate()); + position.setTime(readDate(buf, deviceSession.getTimeZone())); if (buf.readableBytes() == 20) { @@ -609,4 +622,118 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return positions; } + private Position decodeTransparent(DeviceSession deviceSession, ByteBuf buf) { + + int type = buf.readUnsignedByte(); + + if (type == 0xF0) { + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + Date time = readDate(buf, deviceSession.getTimeZone()); + + if (buf.readUnsignedByte() > 0) { + position.set(Position.KEY_ARCHIVE, true); + } + + buf.readUnsignedByte(); // vehicle type + + int count; + int subtype = buf.readUnsignedByte(); + switch (subtype) { + case 0x01: + count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + int id = buf.readUnsignedShort(); + int length = buf.readUnsignedByte(); + switch (id) { + case 0x0102: + case 0x0528: + case 0x0546: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100); + break; + case 0x0103: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedInt() * 0.01); + break; + case 0x052A: + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.01); + break; + case 0x0105: + case 0x052C: + position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.01); + break; + case 0x014A: + case 0x0537: + case 0x0538: + case 0x0539: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01); + break; + default: + switch (length) { + case 1: + position.set(Position.PREFIX_IO + id, buf.readUnsignedByte()); + break; + case 2: + position.set(Position.PREFIX_IO + id, buf.readUnsignedShort()); + break; + case 4: + position.set(Position.PREFIX_IO + id, buf.readUnsignedInt()); + break; + default: + buf.skipBytes(length); + break; + } + break; + } + } + decodeCoordinates(position, buf); + position.setTime(time); + break; + case 0x03: + count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + int id = buf.readUnsignedShort(); + int length = buf.readUnsignedByte(); + switch (id) { + case 0x1A: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 0x1B: + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 0x1C: + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + case 0x1D: + case 0x1E: + case 0x1F: + position.set(Position.KEY_ALARM, Position.ALARM_LANE_CHANGE); + break; + case 0x23: + position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); + break; + default: + break; + } + buf.skipBytes(length); + } + decodeCoordinates(position, buf); + position.setTime(time); + break; + case 0x0B: + if (buf.readUnsignedByte() > 0) { + position.set(Position.KEY_VIN, buf.readCharSequence(17, StandardCharsets.US_ASCII).toString()); + } + getLastLocation(position, time); + break; + default: + return null; + } + + return position; + } + + return null; + } + } diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 8ba6fcaf1..d61dae315 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, buffer( "(794104004140,1,001,BASE,2,TIME)")); + verifyPosition(decoder, binary( + "7E0900005A4E5DE66FBA2200C4F02204280610090002010D052B0150052C0400129009052D016B052E014F05300231BA053502000005360203B8053802000005390200AD053D0201EA05440150054604009899D90545040000001E000C00030160A85C06D1C1389C7E")); + verifyNull(decoder, binary( "7E01000021013345678906000F002C012F373031313142534A2D4D3742203030303030303001D4C1423838383838B47E")); -- cgit v1.2.3 From dcdbbf298e91e04c36c0310ac9c3314000d8781f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 16 May 2022 17:46:25 -0700 Subject: Support Farnear alarms --- .../org/traccar/protocol/GotopProtocolDecoder.java | 19 +++++++++++++++---- .../traccar/protocol/GotopProtocolDecoderTest.java | 14 +++++++++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java index a867451aa..0f8d29228 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@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 GotopProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .number("(d+),") // imei - .expression("[^,]+,") // type + .expression("([^,]+),") // type .expression("([AV]),") // validity .number("DATE:(dd)(dd)(dd),") // date (yyddmm) .number("TIME:(dd)(dd)(dd),") // time (hhmmss) @@ -56,14 +56,25 @@ public class GotopProtocolDecoder 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()); + String type = parser.next(); + if (type.equals("CMD-KEY")) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } else if (type.startsWith("ALM-B")) { + if (Character.getNumericValue(type.charAt(5)) % 2 > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER); + } else { + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); + } + } + position.setValid(parser.next().equals("A")); position.setTime(parser.nextDateTime()); diff --git a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java index bae187959..373858c79 100644 --- a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class GotopProtocolDecoderTest extends ProtocolTest { @@ -12,7 +13,18 @@ public class GotopProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "")); - + + verifyAttribute(decoder, text( + "867688033841044,ALM-B1-1,A,DATE:190622,TIME:144956,LAT:22.7193976N,LON:114.3878200E,Speed:000.1,100-22,03.72"), + Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER); + + verifyAttribute(decoder, text( + "860264050778076,CMD-KEY,V,DATE:220516,TIME:090224,LAT:48.7592616N,LON:003.4658121W,Speed:000.0,057-21,01.60"), + Position.KEY_ALARM, Position.ALARM_SOS); + + verifyPosition(decoder, text( + "860264050778076,CMD-T,A,DATE:220516,TIME:100627,LAT:48.7636978N,LON:003.4652398W,Speed:051.4,077-24,01.00,WIFI:{84-a0-6e-94-42-5e&-47,b2-22-7a-56-5a-2a&-48,b4-b0-24-09-91-d4&-76,18-3c-b7-1f-da-67&-83,08-86-3b-94-78-44&-85,40-24-b2-c5-0f-5e&-87,b0-e5-ed-4e-06-61&-87,60-1d-9d-a6-d2-5d&-88,14-eb-b6-a5-55-8c&-88,40-18-b1-d7-28-54&-88},BLE:{1f-cf-4d-3c-61-bf&-91,39-82-d0-ba-34-69&-57,df-3a-31-ac-ad-72&-73,7c-d9-f4-11-0b-a0&-78,03-b5-9f-45-bd-0d&-88}")); + verifyNull(decoder, text( "353327020412763,CMD-X")); -- cgit v1.2.3 From 433816109a02622145ff5ead295d3aff5bafaacd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 17 May 2022 18:11:09 -0700 Subject: Decode Minifinder pet activity --- .../java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 10 +++++++++- .../org/traccar/protocol/Minifinder2ProtocolDecoderTest.java | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 641a45864..c63226c80 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -263,6 +263,14 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedInt(); // timestamp position.set(Position.KEY_STEPS, buf.readUnsignedInt()); break; + case 0x31: + int i = 1; + while (buf.readerIndex() < endIndex) { + position.set("activity" + i + "Time", buf.readUnsignedInt()); + position.set("activity" + i, buf.readUnsignedInt()); + i += 1; + } + break; case 0x40: buf.readUnsignedIntLE(); // timestamp int heartRate = buf.readUnsignedByte(); diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index ab23f277a..1813a5370 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { var decoder = new Minifinder2ProtocolDecoder(null); + verifyPositions(decoder, binary( + "AB103D0035A700000110013836373733303035333430333237390924AC5783620103C250162030CC5F0D5002FB432D00AF005A3158006D0A00000B0931EC5783620A000000")); + verifyPositions(decoder, binary( "ab10350015ae59010110013836333932313033333836353231360924723a12610042535a182ac0f6b4f2923100c900af02215c2b9bfb5461736b4c4d53")); -- cgit v1.2.3 From 68a1b67be1c7fe9b22805a8d4c1e7a4c7d0bf2ed Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 18 May 2022 18:36:43 -0700 Subject: Handle Ruptela identification --- .../java/org/traccar/protocol/RuptelaProtocolDecoder.java | 15 ++++++++++++++- .../org/traccar/protocol/RuptelaProtocolDecoderTest.java | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 2812d22ff..5a0383358 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,6 +50,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_SMS_VIA_GPRS_RESPONSE = 7; public static final int MSG_SMS_VIA_GPRS = 8; public static final int MSG_DTCS = 9; + public static final int MSG_IDENTIFICATION = 15; public static final int MSG_SET_IO = 17; public static final int MSG_FILES = 37; public static final int MSG_EXTENDED_RECORDS = 68; @@ -306,6 +307,18 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { return null; + } else if (type == MSG_IDENTIFICATION) { + + ByteBuf content = Unpooled.buffer(); + content.writeByte(1); + ByteBuf response = RuptelaProtocolEncoder.encodeContent(type, content); + content.release(); + if (channel != null) { + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + + return null; + } else { return decodeCommandResponse(deviceSession, type, buf); diff --git a/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java index 64ac6a57e..eca7518a7 100644 --- a/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class RuptelaProtocolDecoderTest extends ProtocolTest { var decoder = new RuptelaProtocolDecoder(null); + verifyNull(decoder, binary( + "002e000316d53d58d6020f4573303430302e30332e36382e30340000c2b3090d0e950000827b000003e80000003c003c1681")); + verifyPositions(decoder, binary( "00800003167d765c155d01000160cd0a310000faae43f7176ee45702332b0c12000006070d05007300cfff260082008600870088000f00d7021100d801c900061d0000c500001e0e988300008900008b000002d0000c9bca720c889a0b047e00000000000000007f0000000000000000800000000000000000810000000000000000a341")); -- cgit v1.2.3 From 445acb5da5ba9e321a016630d58147c7e69fe916 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 May 2022 14:09:26 -0700 Subject: Initialize device location --- tools/test-map.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/test-map.py b/tools/test-map.py index c289df605..ab4466b09 100755 --- a/tools/test-map.py +++ b/tools/test-map.py @@ -38,6 +38,7 @@ conn = httplib.HTTPConnection(server) for i in range(devices): device_id = "{0:0>6}".format(i) add_device(cookie, device_id) + send_message(conn, device_id) while True: device_id = "{0:0>6}".format(random.randint(0, devices)) -- cgit v1.2.3 From 4616e04a34e42e8f415c31fa3b871d9ab2608c96 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 May 2022 14:11:30 -0700 Subject: Rename changelog version --- schema/changelog-4.16.xml | 27 --------------------------- schema/changelog-5.0.xml | 33 +++++++++++++++++++++++++++++++++ schema/changelog-master.xml | 3 ++- 3 files changed, 35 insertions(+), 28 deletions(-) delete mode 100644 schema/changelog-4.16.xml create mode 100644 schema/changelog-5.0.xml diff --git a/schema/changelog-4.16.xml b/schema/changelog-4.16.xml deleted file mode 100644 index 8bf3a41d5..000000000 --- a/schema/changelog-4.16.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/schema/changelog-5.0.xml b/schema/changelog-5.0.xml new file mode 100644 index 000000000..0e8474eef --- /dev/null +++ b/schema/changelog-5.0.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index d79e084f6..bb2b3e2f3 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -29,6 +29,7 @@ - + + -- cgit v1.2.3 From 24197b483c932c473ef14fb8efff4d368b2559fe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 May 2022 15:26:56 -0700 Subject: Update version numbers --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 0b3f54355..25c8a32e3 100644 --- a/build.gradle +++ b/build.gradle @@ -95,7 +95,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "4.15", + "Implementation-Version": "5.0", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 3ffab1289..64137f8d6 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=4.15 +AppVersion=5.0 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index ac0d73d5b..77100dd32 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "4.15", + "version": "5.0", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From 56f742c2e3e009c6af74fec689c459958d8945e7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 May 2022 15:45:57 -0700 Subject: Fix user creation --- src/main/java/org/traccar/database/UsersManager.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/traccar/database/UsersManager.java b/src/main/java/org/traccar/database/UsersManager.java index 31759dc8b..a54226cfe 100644 --- a/src/main/java/org/traccar/database/UsersManager.java +++ b/src/main/java/org/traccar/database/UsersManager.java @@ -59,6 +59,12 @@ public class UsersManager extends SimpleObjectManager { } } + @Override + public void addItem(User user) throws StorageException { + super.addItem(user); + getDataManager().updateUserPassword(user); + } + @Override public void updateItem(User user) throws StorageException { if (user.getHashedPassword() != null) { -- cgit v1.2.3 From d9f51795058399e85ae83a8e308a0c2bc1d13e4b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 May 2022 16:16:32 -0700 Subject: Update git commit --- traccar-web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traccar-web b/traccar-web index 9e1c0b441..d6445273b 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit 9e1c0b44189136ec6abf05720c698027a689fa08 +Subproject commit d6445273b78fef8e5a081402f6ca6eb69ea952b2 -- cgit v1.2.3 From 6c4294b9a3f59c9615be74c04d4c8e047ef3ff4f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 22 May 2022 11:00:14 -0700 Subject: Fix style issue --- src/main/java/org/traccar/storage/DatabaseStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index ff77ff8a8..388fd4016 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -319,7 +319,7 @@ public class DatabaseStorage extends Storage { result.append(" UNION "); result.append("SELECT DISTINCT "); - result.append(expandDevices? "devices." : "groups."); // TODO handle reverse search (e.g. users by device) + result.append(expandDevices ? "devices." : "groups."); // TODO handle reverse search (e.g. users by device) result.append(outputKey); result.append(" FROM "); result.append(groupStorageName); -- cgit v1.2.3 From d2b164d54e4ae831b562ca7917d3117f2fe78c24 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 22 May 2022 13:26:22 -0700 Subject: Fix permission requests --- src/main/java/org/traccar/api/ExtendedObjectResource.java | 4 ++-- src/main/java/org/traccar/storage/query/Condition.java | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 40d679ded..1c306630c 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -56,11 +56,11 @@ public class ExtendedObjectResource extends BaseObjectResou if (groupId > 0) { permissionsService.checkPermission(Group.class, getUserId(), groupId); - conditions.add(new Condition.Permission(Group.class, groupId, baseClass)); + conditions.add(new Condition.Permission(Group.class, groupId, baseClass).excludeGroups()); } if (deviceId > 0) { permissionsService.checkPermission(Device.class, getUserId(), deviceId); - conditions.add(new Condition.Permission(Device.class, deviceId, baseClass)); + conditions.add(new Condition.Permission(Device.class, deviceId, baseClass).excludeGroups()); } return storage.getObjects(baseClass, new Request(new Columns.All(), Condition.merge(conditions))); diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 91ede236c..4cfdc907f 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -165,10 +165,6 @@ public interface Condition { this(ownerClass, ownerId, propertyClass, 0, false); } - public Permission(Class ownerClass, Class propertyClass, long propertyId) { - this(ownerClass, 0, propertyClass, propertyId, false); - } - public Permission excludeGroups() { return new Permission(this.ownerClass, this.ownerId, this.propertyClass, this.propertyId, true); } -- cgit v1.2.3 From 402fd2b7faf1528f887de22d8175ccd80acf24a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 22 May 2022 13:34:16 -0700 Subject: Another permission optimization --- src/main/java/org/traccar/api/ExtendedObjectResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 1c306630c..6037118dd 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -47,11 +47,11 @@ public class ExtendedObjectResource extends BaseObjectResou permissionsService.checkAdmin(getUserId()); } else { if (userId == 0) { - userId = getUserId(); + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); } else { permissionsService.checkUser(getUserId(), userId); + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass).excludeGroups()); } - conditions.add(new Condition.Permission(User.class, userId, baseClass)); } if (groupId > 0) { -- cgit v1.2.3 From 69d45b4429be70ce079b51200f6baefeb3873220 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 23 May 2022 18:22:42 -0700 Subject: Self access permission --- src/main/java/org/traccar/api/security/PermissionsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index c640f8d74..e7955086a 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -126,7 +126,7 @@ public class PermissionsService { public void checkPermission( Class clazz, long userId, long objectId) throws StorageException, SecurityException { - if (!getUser(userId).getAdministrator()) { + if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) { var objects = storage.getObjects(clazz, new Request( new Columns.Include("id"), new Condition.Permission(User.class, userId, clazz))); -- cgit v1.2.3 From fed6597faa141ba3ee8b11bff2c987ac981fd91b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 May 2022 08:59:27 -0700 Subject: Include address in login logs --- .../java/org/traccar/api/resource/SessionResource.java | 5 ++--- src/main/java/org/traccar/helper/LogAction.java | 17 ++++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 8422e0b49..136aab0eb 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -110,8 +110,7 @@ public class SessionResource extends BaseResource { @FormParam("email") String email, @FormParam("password") String password) throws StorageException { User user = Context.getPermissionsManager().login(email, password); if (user != null) { - request.getSession().setAttribute(USER_ID_KEY, user.getId()); - LogAction.login(user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); return user; } else { LogAction.failedLogin(ServletHelper.retrieveRemoteAddress(request)); @@ -121,7 +120,7 @@ public class SessionResource extends BaseResource { @DELETE public Response remove() { - LogAction.logout(getUserId()); + LogAction.logout(getUserId(), ServletHelper.retrieveRemoteAddress(request)); request.getSession().removeAttribute(USER_ID_KEY); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/helper/LogAction.java b/src/main/java/org/traccar/helper/LogAction.java index d16b25483..b255b9206 100644 --- a/src/main/java/org/traccar/helper/LogAction.java +++ b/src/main/java/org/traccar/helper/LogAction.java @@ -47,7 +47,7 @@ public final class LogAction { private static final String PATTERN_OBJECT = "user: %d, action: %s, object: %s, id: %d"; private static final String PATTERN_LINK = "user: %d, action: %s, owner: %s, id: %d, property: %s, id: %d"; - private static final String PATTERN_LOGIN = "user: %d, action: %s"; + private static final String PATTERN_LOGIN = "user: %d, action: %s, from: %s"; private static final String PATTERN_LOGIN_FAILED = "login failed from: %s"; private static final String PATTERN_DEVICE_ACCUMULATORS = "user: %d, action: %s, deviceId: %d"; private static final String PATTERN_REPORT = "user: %d, report: %s, from: %s, to: %s, devices: %s, groups: %s"; @@ -72,12 +72,12 @@ public final class LogAction { logLinkAction(ACTION_UNLINK, userId, owner, ownerId, property, propertyId); } - public static void login(long userId) { - logLoginAction(ACTION_LOGIN, userId); + public static void login(long userId, String remoteAddress) { + logLoginAction(ACTION_LOGIN, userId, remoteAddress); } - public static void logout(long userId) { - logLoginAction(ACTION_LOGOUT, userId); + public static void logout(long userId, String remoteAddress) { + logLoginAction(ACTION_LOGOUT, userId, remoteAddress); } public static void failedLogin(String remoteAddress) { @@ -105,8 +105,11 @@ public final class LogAction { Introspector.decapitalize(property.getSimpleName()), propertyId)); } - private static void logLoginAction(String action, long userId) { - LOGGER.info(String.format(PATTERN_LOGIN, userId, action)); + private static void logLoginAction(String action, long userId, String remoteAddress) { + if (remoteAddress == null || remoteAddress.isEmpty()) { + remoteAddress = "unknown"; + } + LOGGER.info(String.format(PATTERN_LOGIN, userId, action, remoteAddress)); } public static void logReport( -- cgit v1.2.3 From 0ba89aa35180f965e8c8ca85560d7ee7a1849b3c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 May 2022 09:02:56 -0700 Subject: Fix login issue --- src/main/java/org/traccar/api/resource/SessionResource.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 136aab0eb..1ccba1270 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -110,6 +110,7 @@ public class SessionResource extends BaseResource { @FormParam("email") String email, @FormParam("password") String password) throws StorageException { User user = Context.getPermissionsManager().login(email, password); if (user != null) { + request.getSession().setAttribute(USER_ID_KEY, user.getId()); LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); return user; } else { -- cgit v1.2.3 From 284de955abc4526fd988f350666558f57db1507f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 May 2022 17:02:52 -0700 Subject: Decode A1L808 lock info --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 13 ++++++++++++- .../org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index c280ee9b2..9f54c8486 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -493,7 +493,18 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; case 0xD5: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + if (length == 2) { + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + } else { + int count = buf.readUnsignedByte(); + for (int i = 1; i <= count; i++) { + position.set("lock" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(5))); + position.set("lock" + i + "Card", ByteBufUtil.hexDump(buf.readSlice(5))); + position.set("lock" + i + "Battery", buf.readUnsignedByte()); + int status = buf.readUnsignedShort(); + position.set("lock" + i + "Locked", !BitUtil.check(status, 5)); + } + } break; case 0xDA: buf.readUnsignedShort(); // string cut count diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index d61dae315..c45effbc5 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, buffer( "(794104004140,1,001,BASE,2,TIME)")); + verifyAttribute(decoder, binary( + "7E02000053200002604323004800000000000C00000158B91406CB7007006B00000000220512101138010400000F2803020000250400000000300114310100E30100D50E0100026043232795980277530030E50400000000E7020FC8E8020E83AB7E"), + "lock1Locked", false); + verifyPosition(decoder, binary( "7E0900005A4E5DE66FBA2200C4F02204280610090002010D052B0150052C0400129009052D016B052E014F05300231BA053502000005360203B8053802000005390200AD053D0201EA05440150054604009899D90545040000001E000C00030160A85C06D1C1389C7E")); -- cgit v1.2.3 From 8e8a435cea0ea44dfcb20b45dcbb881b87361676 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 25 May 2022 07:14:36 -0700 Subject: Avoid using MySQL keywords --- src/main/java/org/traccar/storage/DatabaseStorage.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 388fd4016..e8966be8e 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -319,7 +319,7 @@ public class DatabaseStorage extends Storage { result.append(" UNION "); result.append("SELECT DISTINCT "); - result.append(expandDevices ? "devices." : "groups."); // TODO handle reverse search (e.g. users by device) + result.append(expandDevices ? "devices." : "all_groups."); // TODO handle reverse (e.g. users by device) result.append(outputKey); result.append(" FROM "); result.append(groupStorageName); @@ -339,16 +339,16 @@ public class DatabaseStorage extends Storage { result.append(getStorageName(Group.class)); result.append(" AS g1 ON g2.id = g1.groupid"); result.append(" WHERE g2.groupid IS NOT NULL"); - result.append(") AS groups ON "); + result.append(") AS all_groups ON "); result.append(groupStorageName); - result.append(".groupid = groups.parentid"); + result.append(".groupid = all_groups.parentid"); if (expandDevices) { result.append(" INNER JOIN ("); result.append("SELECT groupid as parentid, id as deviceid FROM "); result.append(getStorageName(Device.class)); result.append(" WHERE groupid IS NOT NULL"); - result.append(") AS devices ON groups.groupid = devices.parentid"); + result.append(") AS devices ON all_groups.groupid = devices.parentid"); } result.append(" WHERE "); -- cgit v1.2.3 From 79b5d08f45e8be4ff7d0072cd91fed39d5afe117 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 May 2022 16:46:35 -0700 Subject: Fix null server --- src/main/java/org/traccar/api/security/PermissionsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index e7955086a..4d5cd88ab 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -68,7 +68,7 @@ public class PermissionsService { public void checkReports(long userId) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator() - && (server.getDisableReports() || getUser(userId).getDisableReports())) { + && (getServer().getDisableReports() || getUser(userId).getDisableReports())) { throw new SecurityException("Reports are disabled"); } } -- cgit v1.2.3 From 8ed7d6cd19f221c40e9994c0469009ff9c0e46b1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 May 2022 17:27:10 -0700 Subject: Fix several manager issues --- src/main/java/org/traccar/api/ExtendedObjectResource.java | 4 +++- src/main/java/org/traccar/api/SimpleObjectResource.java | 4 +++- .../java/org/traccar/api/security/PermissionsService.java | 12 +++++++++--- src/main/java/org/traccar/storage/DatabaseStorage.java | 6 +++++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 6037118dd..e49f67bb9 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -44,7 +44,9 @@ public class ExtendedObjectResource extends BaseObjectResou var conditions = new LinkedList(); if (all) { - permissionsService.checkAdmin(getUserId()); + if (!permissionsService.isAdmin(getUserId())) { + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); + } } else { if (userId == 0) { conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); diff --git a/src/main/java/org/traccar/api/SimpleObjectResource.java b/src/main/java/org/traccar/api/SimpleObjectResource.java index c61101077..15a496c5f 100644 --- a/src/main/java/org/traccar/api/SimpleObjectResource.java +++ b/src/main/java/org/traccar/api/SimpleObjectResource.java @@ -41,7 +41,9 @@ public class SimpleObjectResource extends BaseObjectResourc var conditions = new LinkedList(); if (all) { - permissionsService.checkAdmin(getUserId()); + if (!permissionsService.isAdmin(getUserId())) { + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); + } } else { if (userId == 0) { userId = getUserId(); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 4d5cd88ab..ac687fc1c 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -21,6 +21,7 @@ import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.GroupedModel; +import org.traccar.model.ManagedUser; import org.traccar.model.ScheduledModel; import org.traccar.model.Server; import org.traccar.model.User; @@ -60,9 +61,13 @@ public class PermissionsService { return user; } + public boolean isAdmin(long userId) throws StorageException { + return getUser(userId).getAdministrator(); + } + public void checkAdmin(long userId) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { - throw new SecurityException("Account is readonly"); + throw new SecurityException("Administrator access required"); } } @@ -118,7 +123,7 @@ public class PermissionsService { public void checkUser(long userId, long managedUserId) throws StorageException, SecurityException { if (userId != managedUserId && !getUser(userId).getAdministrator()) { if (!getUser(userId).getManager() - || storage.getPermissions(User.class, userId, User.class, managedUserId).isEmpty()) { + || storage.getPermissions(User.class, userId, ManagedUser.class, managedUserId).isEmpty()) { throw new SecurityException("User access denied"); } } @@ -129,7 +134,8 @@ public class PermissionsService { if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) { var objects = storage.getObjects(clazz, new Request( new Columns.Include("id"), - new Condition.Permission(User.class, userId, clazz))); + new Condition.Permission( + User.class, userId, clazz.equals(User.class) ? ManagedUser.class : clazz))); boolean found = false; for (var object : objects) { if (object.getId() == objectId) { diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index e8966be8e..cd82448e1 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -128,9 +128,13 @@ public class DatabaseStorage extends Storage { conditions.add(new Condition.Equals( Permission.getKey(propertyClass), Permission.getKey(propertyClass), propertyId)); } - query.append(formatCondition(Condition.merge(conditions))); + Condition combinedCondition = Condition.merge(conditions); + query.append(formatCondition(combinedCondition)); try { QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + for (Map.Entry variable : getConditionVariables(combinedCondition).entrySet()) { + builder.setValue(variable.getKey(), variable.getValue()); + } return builder.executePermissionsQuery(); } catch (SQLException e) { throw new StorageException(e); -- cgit v1.2.3 From 950a35723b8ad3e9383c55d8b84812d012da3085 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 May 2022 17:41:16 -0700 Subject: Fix wrong user permissions (fix #4853) --- src/main/java/org/traccar/api/ExtendedObjectResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index e49f67bb9..41ed3e9d9 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -52,7 +52,7 @@ public class ExtendedObjectResource extends BaseObjectResou conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); } else { permissionsService.checkUser(getUserId(), userId); - conditions.add(new Condition.Permission(User.class, getUserId(), baseClass).excludeGroups()); + conditions.add(new Condition.Permission(User.class, userId, baseClass).excludeGroups()); } } -- cgit v1.2.3 From bb50a4178d171d40734b94fccf52b72733f1f04c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 27 May 2022 19:28:31 -0700 Subject: Watch zero cell towers --- .../org/traccar/protocol/WatchProtocolDecoder.java | 24 ++++++++++++---------- .../traccar/protocol/WatchProtocolDecoderTest.java | 3 +++ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 4ab7875b7..b25a15f93 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -145,17 +145,19 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { int cellCount = Integer.parseInt(values[index++]); index += 1; // timing advance - int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; - int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; - - for (int i = 0; i < cellCount; i++) { - int lac = Integer.parseInt(values[index++]); - int cid = Integer.parseInt(values[index++]); - String rssi = values[index++]; - if (!rssi.isEmpty()) { - network.addCellTower(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(rssi))); - } else { - network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + if (cellCount > 0) { + int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; + int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; + + for (int i = 0; i < cellCount; i++) { + int lac = Integer.parseInt(values[index++]); + int cid = Integer.parseInt(values[index++]); + String rssi = values[index++]; + if (!rssi.isEmpty()) { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(rssi))); + } else { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid)); + } } } diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 4fab19f26..34ef7839b 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -15,6 +15,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { var decoder = new WatchProtocolDecoder(null); + verifyPosition(decoder, buffer( + "[3G*9031853319*004E*UD2,220322,055105,A,22.761162,N,114.360192,E,0,0,47,14,100,64,0,0,00000008,0,0]")); + verifyAttribute(decoder, buffer( "[3G*2104326058*000E*btemp2,1,35.29]"), Position.PREFIX_TEMP + 1, 35.29); -- cgit v1.2.3 From 56af285413c2337079332f303f7d091d65f09c4e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 28 May 2022 06:31:55 -0700 Subject: Decode G6W audio format --- src/main/java/org/traccar/helper/BufferUtil.java | 12 +++++++ .../org/traccar/protocol/WatchProtocolDecoder.java | 39 +++++++++++++++++----- .../traccar/protocol/WatchProtocolDecoderTest.java | 3 ++ 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/helper/BufferUtil.java b/src/main/java/org/traccar/helper/BufferUtil.java index 9485c17c6..1e1a687fa 100644 --- a/src/main/java/org/traccar/helper/BufferUtil.java +++ b/src/main/java/org/traccar/helper/BufferUtil.java @@ -27,6 +27,18 @@ public final class BufferUtil { private BufferUtil() { } + public static int indexOf(ByteBuf buffer, int fromIndex, int toIndex, byte value, int count) { + int startIndex = fromIndex; + for (int i = 0; i < count; i++) { + int result = buffer.indexOf(startIndex, toIndex, value); + if (result < 0 || i == count - 1) { + return result; + } + startIndex = result + 1; + } + return -1; + } + public static int indexOf(String needle, ByteBuf haystack) { return indexOf(needle, haystack, haystack.readerIndex(), haystack.writerIndex()); } diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index b25a15f93..420866578 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,14 +18,13 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; +import org.traccar.helper.BufferUtil; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -41,7 +40,7 @@ import java.util.regex.Pattern; public class WatchProtocolDecoder extends BaseProtocolDecoder { - private static final Logger LOGGER = LoggerFactory.getLogger(WatchProtocolDecoder.class); + private ByteBuf audio; public WatchProtocolDecoder(Protocol protocol) { super(protocol); @@ -318,13 +317,37 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type.equals("JXTK")) { + + int dataIndex = BufferUtil.indexOf(buf, buf.readerIndex(), buf.writerIndex(), (byte) ',', 4) + 1; + String[] values = buf.readCharSequence( + dataIndex - buf.readerIndex(), StandardCharsets.US_ASCII).toString().split(","); + + int current = Integer.parseInt(values[2]); + int total = Integer.parseInt(values[3]); + + if (audio == null) { + audio = Unpooled.buffer(); + } + audio.writeBytes(buf); + + sendResponse(channel, id, index, "JXTKR,1"); + + if (current < total) { + return null; + } else { + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + getLastLocation(position, null); + position.set(Position.KEY_AUDIO, Context.getMediaManager().writeFile(id, audio, "amr")); + audio.release(); + audio = null; + return position; + } + } else if (type.equals("TK")) { if (buf.readableBytes() == 1) { - byte result = buf.readByte(); - if (result != '1') { - LOGGER.warn(type + "," + result); - } return null; } diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 34ef7839b..ef6c33da9 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -15,6 +15,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { var decoder = new WatchProtocolDecoder(null); + verifyNull(decoder, binary( + "5b5a4a2a3738393436383035303034323639322a303033342a303433392a4a58544b2c302c77617463685f375f32303232303532363039333935342c312c362c2321414d520a0c0a3c3f96d98367e9468ea245320c0a3c3f96d98367e9468ea245320c0a3c3f96d98367e9468ea245320c389814ffcd762fe49d50ae7a2e0cb528aefbf76911df05c2fbe17d050c2200cff77ef0df4d9b4ab9a4340c449814dbe7c63fa82bc3750d800cc48abbffddb0df8e8fda95e5980c49982ff6cf65f9377d02a39c3aaa0c389805f2ff42c1b80e0a0eb1dc0c2998e9defe15cfa3bdbe80d3540c7298c2f6d9239e3eae3c4a81660c490034dbfd513fedad0c2fc3900cc40039b7f71bb0657ba75558c40cd7813b97ff7219777ec7f401260c7d040003bff6f75fdb898a6ba1140cecd127f7f83357cb73a68a5f680cb081d4f6e749e6af8ed367bc480cec1815dfffd2dbed358112af320ccc21179fffbd17a3a61c133b380c920047defc72a784770ec0fe400c383c42f6faebe76fa736e9d1be0c4918e7decddc67ec9afd87ff220cc418e6bffe6cf6c9ac1f83c3900ca6cad1ffe3da24e1be3b547d03c00c6b00b8fee77f60a76d3e7d0292e20c2918b7bfff76387b793d3a36300c7d0400b7fff7f63ae513ac6f74de0c980016fbff7d01f9b30fca67c7220caa982ff6dbd7bf3d8dfed143ec0c44982fdfcb7b517e26f6ea52420c0ed19cfedb438f179d3fc50ec40c008ad2ffff635fe28dc1ec1f860c76cb7d05bffda53eaebe4d201ae20ccccaffbbfd3db4abb6ddf39d0e0c6b00acfeff406fe4a12661caf80c76982fbffffeb17b2f65472f300c7d04c24bf6ef1b10e47f73fc10b40c76036cfecd4e7837145a6a8e900ccccaf2beeba36fbaa36feb60640c7d0400dfffff73bfa3b87d0256a1700c7d04e4efd6efc23b651eb73e77780ccc1813ffffb39f6baa6f3195080c00007afffee0b9df6346ca08d00c6bca7d04feff4d64a7b56f9855da0c769819fbfd954ea5bd7d040ba6420c4c4c09bfffd5f6c57d01930e7d01220cc48a22dffe30bfcbaf08a795140c7d040433b7ff3cba5f3e336a40060cecbd2bfaf775bea7bde7e095ee0cc4caaef7fb623feeaab69eabc20c8c0021bffd1ea4a1b090175a920c7d046445fbdfc1abe910b0ca56160c7d0440cbd7ef03893c7f7d02e1a8c20c85e42dff5fdaa145759d326b5a0ccc4084f75f8eeb7b15e4eb4ff80c6bc22ef7d7eaf8df3b8ff678cc0cca4026f3cf7518fd731ceca3560cec041ffbe7655eaf822f04c4fe0c7d0478e3fbfcb5dfc8a81fdbb9e20cc418e6d7ff777f26affe37cc020cd7977cbff7d0aecb9727be6a0c0c00bde1f2d797fc8754ed09d4ae0cc498279f7e729fcb9eff70c1a60c7d0478e5bfffc67eef953fda69aa0c7200f1bbf7e891ef5a287cb5b80c983629fee5555f739f8a29279a0c76d103bef73f55a6bf89ba8ce40cc46424f6ded9a194167a067d05880cc4780efeffc37fae944d89bfb40c4464bffffb6dd54e8344394a5c0c49781ffffc653feaa31af59ac00cc464cebfd76ae4e8a55d5b5a4a2a3738393436383035303034323639322a303033352a303434332a4a58544b2c302c77617463685f375f32303232303532363039333935342c322c362c5f24fbbc0c7d04983effcfe35fbd8fff7ce6f60c448a1dfbd715bec3b42448e58a0c0e0421bf5f17ebc31a43301bc40c768ababf4f66cf629ee31fe9900c6b6426bf5f4eb7669dacc439140c945733bff9351e7d04ab6be54ef60ccc98bfbffbf67f63b78d8f42880c7d0400c6f7fffab5cbae8e8275da0c0097ffdefff5dfafb0c4727d04980ccc78d1f6ff1a6b7e37631059fa0c760045f3fd853fea877d03aa87440cc40022f7ffa8b5c58f6e80c58e0ccc4c1f9ffff32fa7af87de04560cb09801f6fdd32efcbdad9495b60c6b987d05bff72d61eb687d05a9f9e20cca57c7ffff6cb1fe3387ea596e0c629823dedfbfc50b97965e44ea0c4918ccbfd7cc75e59fff92e9ee0c8c78e7faff707ffda60ec3ada60c30c217befffcb8f3290f06d75e0c0e8a7bb7dff3eec7b7928ef6680c38ca1cdeff272ba012597d051a520c0018dfffeff27d01e369b3bcd7d80c98146eb2fc7f45c38e1ce53e120c3d5700ff7fd44bee28aa089d900c007157bffffe30302d7d0583585c0ccc5747bfe7f73cff7d02de1098240c7d047865f6feca71d70bdfaab6a20cecb946bfd966be74b61a06c6660c441612ffe7eb966a8c2886cf760ccc7827bffd653ff7980a62e9320c00ca98f7fc1b311a3986700cc20c490017bfff70cfe7bb455637320c6228afbf7e6da4c59763b693740cccc2b5fee1951975760e4a9dca0c0000faffdb255f6f86af4be6fc0cccc2ffdfff7d0225efbc847c42760cb48a8fdffbe23ff1a78782cbe60c7d04980cffff6e6dfc75a6c65a500ce62808bfff24f853748a9537400cb4004ebfeb6e70aa4314903e8c0cb46408ff72d62f44945f64897d040cccca7abfff2db5c6bfcc345e700c7d04c24dd6fd5f95638f78974a800cc4caffffffb17d01c36bdd7d047c2e0c7d0436d1f7f8917f83af7fc5c2180c070449f6fe570f128577c8c97d040c7d047813f6df3fd17d026b6790d1b80cc400c9d6d92dc56497843ed10a0c44986effffe13fef8eef7c717a0c7d049872bbfdad3abe2be0d60b240c4900adbf7d02dfa4ef960fdf23580c629845fefc5a650fbf8b0d4cda0c7d040076b7ef273fe78fce983ae40c4a00ded7ff629f7fab4531501c0c6200b7ffedf13fe6a68f01fb6c0cc49809f77fdb91517fb39e8ba00c760009bf7fd6afe7b46921f27a0cecbd1df6faf99120776e807d03fe0c98ca23fbff3749fb5ed3909c160cc44cbbbfffbd70e77d0367bc2e740c499816f77fe2ffe08edd7d048c9e0c940021beff1df0f1338c2f1a3a0c7d040083feebba1c756e5760c2200c94981dfffdf921b92b99909ba40c7d04984ebbdf7ff0c77d025a1fbfc00c7657b3ff77f4befcae2bf625640c62ca53f7fdb35f2e92af3bd5c60c7d049878bbdfc0dfc1bdaa1918000cc404bbbfefb41ee6b50a39bf180c767874f7fb8ee156320ee600020c69981cffffe0fff6bb2764acaa0cec781bfbff7d0324eb9b4b4d5d5b5a4a2a3738393436383035303034323639322a303033362a303433302a4a58544b2c302c77617463685f375f32303232303532363039333935342c332c362c73580c07ca4fbbfff5bec5abcfac465c0c0042a8beff316aed38fe4603dc0c7d04577d04fefdc929f7294ce7520c0c76984dfaff402fe68ebe113b000c7d0436a6fed465ff4f8d8e3306300c44e434f7f79e84abb8fa081be80c983636bef7e128bf7d03d34c71c80cd7982dffd54cac94536beab1320c058bd6bfff701fe69d1a39d1e80c76caedb77ffea0e47febb469440c0098b2bef5e55eed981672b1c40cd800d1bef4bda58daf7d01d309180c08cadffbfc31799f5613fab2da0c7d049828beffa5eea0bd09a14c2e0c0000e59feb5f9dff7f4945e98e0cc40046ffcfe57fb58f7d053dd9e20c7d040047d7ffd38f67aa9db8d38c0c7698d2df5fe2efc6bb0f5a18220c980367bbfd95dae73e3bf2b59a0c49813796fdf5efab9d3ed7d3d80c9800ebd7fdb831ae8f91811e920c7d04ca74bbff5cdcf45605c25f140c013e029fbfe7ffc299376b409a0c7510009e7d02010f68824cccead60cb13b00f7d5821e6c8d594a06880c75ec00f6e782e8f06b0c610d1a0cc09843dfef117fa5b3aef236f40cdcc208ffff4831f83703ca20c00cc09800bf7fd71eec9ba34e3c200c650f6bffd5bc4dbe7ec5b0f1d80c0d1c1f92ef917fa0b96023eac00c8efb1db6bfa42eed9f69051d4e0c8eff23b2fe4486d56ef44f702e0c8ebc1b9657d46eeea852ac337e0c8efb1f96d9877fc9b34c38f1540c121c2796df13577c727f8cedec0ca9107d05afdd6a9d957ab76c02560c121c2dd6bfd33fa5b844f27d02340cb11037b6e3962e6eaf52d6e7460c2b1c3db2dfe61eef9aad3dcc0a0c542e42d763e709fe723a83ae7c0c7cfa56bf7fedb8763c3f8ab2c00ca40022efff2411604d22a485e00c228adcbfdfcd748293c66b0bf20cb10f0097ff806dcf7a0a640d6e0c5a0400b7e3030ef4ae0a6046f80cb82812fe7b04d77e4bab11894a0c541c24b2dd53fea5891e3824420ca9fb26b2d7156fa485049cac420ca91c2d9edb2487526c2e2260fa0ca9bc25b65ff28e41a34232c0f00c8efb25b649e51ec39c0ae6703a0c70f425a6c820dfaf2f8124c8960c80f42794b323aed9ca9b6924be0cb93b278e3e8d929c36bb70b6360c587b27524f85857d056d214841660cda2f278b4c876eb3186e5acc540ce6832f6e3f0d82f81226e6dc3a0c0b922feff50a03d03c98ae28360c03d62befb54ab611de0c8addee0c84d626b7fdb4461556dc0153040c0b0f27ff5781c5c2b32f6762140c49bf2dfaf521969b702ecb11d80c7d050f27cfed75bfab95dc4af3180c011c3d8e7451df80a5cd0948080c7c2e35f2c7b0becca22e50769e0c7c1c3d965e628f46a9a58ae6100c7c2e3b965f4a6b5ebd1436b0b00c7c863eaedf18c7816cdeeed7e20c2b3e3df6b73952b2b1abc048a00c7cfb3db6cd67ae68cda18af9d60c2bff3e96df12ff61b39627cd580c7c863fd6cd810ee595d85ee6645d5b5a4a2a3738393436383035303034323639322a303033372a303433372a4a58544b2c302c77617463685f375f32303232303532363039333935342c342c362c0c7cff3fb65f812fe196dc62d8360c7c2e3db2de738fae9ca7c7236c0c2b2e3d96df6c1d775a3df5a47e0c7c3e3f96fe943dc07e81e170700c75503fb7d6a6197f1b08df85440c5a133ab6d6a0e68f3acb04b7b00cfa293fd6cfc20c390d5265d3c80c581347b278077d03dc22d9e49c680ce64d47924e8dcdffe9be19dc100cb90f4f9e612d2201961c2e111c0c003b4febb58a96c809ab5a71040ce6d759fbddba54b2aa9d9d983e0cc029576ecf1f703099d84994520c4029579e7d0281577073f5629dd80c5a2952b6fed177177d01e57d0175c20cd8647d044f7e3c58aba523ddb0720cb56753d3e9c6799f95938401f60c756414ff5f00fb57bc4d7e111c0c7c085573ef743ee19ca30057e00c752e5ab77e34eec69f3cbe53940c542e4d96d6e7ff03854a9506620c7cff55b6efca197610a86606180c7cfb55b67eb25f4b999c002bf20c7c107d03beeb451fad8d042492740cb8f05eb5ff664f679c1cc991c60ce1671bffd33d9445b57d0584c7d60c07781dfef5e3ee81b45ff8a8c80cc40072b7dfe6fe6e978257253a0cb1131fe6783035868e439b00d80c583b27b17ecb53dd165c3422180c703b2fbeb18d023e14d90304700c3cce2b93cdc2e6b3550a5546160cb13b3b72fe24273859059b52040c224d34edc742f6bb7c877d02b5940cb84d37cdcfcbc3f03a041cf4ac0ca4923a9f3b74e805b235cce8660c759000fbfd90565072aa7d03bb520cb592017f411dcbe80a0cc420360c09d6528fcf2e25b382ee46d75a0ce2e853d3cfb617fd7d023f05e0780c07cc3bbabfa9f6cec5aa48ac600c404208fb678a4cf16a9c09098c0cf14244fbdfc2afe7932fe57d02900c011c369e7d0264a8570a54f9a2e80cb1103daed6249fe59dc888c2ac0cb1103573c5f697be759923ecc80c705f7d059effaaa4b09b976f375a0c804223bbed89767d041693edab180cb49819d7eb5a8573bb10c951540c3c643af74f021f25b6dd3b7d02040c07982bd73fb31fe38f09a227a40c037610ff7d03c6058098fef936a80c03b808debbe055a1a71319128c0c6b8f2e9e3bb52d71c226d3141a0cdab82d7fa9d416167a1cb950020c03c32bb23ee9e3743f3b6853060cc02937adb5157d05f4a6960c1b680c4076365e6b754bda9394a7aa720c06293ef23313fb1b94bcc2c09a0ce676006bbd8e0417941b90d23c0cb9294f7d01fd3d65748cf6d1cc220c03767d035e3a65e6f2514ab1db060ce6d965bf4035f65c79a9e4446a0ce62921dbf46457b56cd65f6c500c584d6bba7ea8166edd6cf7693a0cb939227bfca25f82a7c4202f2e0c06ce2b9a4f0d95f39eb43c22840c06901eef6fd15fe48f452000e00c62023afbffb269beba0ee0ac540ce6ec00f37b8139f2026e80f1440c22501dfe7d017d03ed8c3ff6803f240cc48ae3b7fd725e63a347cd64100c0094f8efdeb0a9f35c83eb06b00c005d5b5a4a2a3738393436383035303034323639322a303033382a303433332a4a58544b2c302c77617463685f375f32303232303532363039333935342c352c362c6647deef2df57fb68fd76b660c44e43cbfefc0beec867d025c3f920cb4507d01ff6f42ee6c1f58a0db0e0c7d045701ff7f19f9f90fdff037c20c4404259efcd47d02a52b7ef6df0e0c7d04d128f3578db14779993109560ce1e41ecffd2851af49256b1ecc0c7d049837ffff707168db3dd1ac240cc09419f7f39a7d013d6ec1b4e55c0cc4881cff5f49f55fadc52285a40c06ce9ad7dbb8349b97031ac3b00c407d049d9bed74dfadad950eab560c06799ffac7a924b18bdf11c3d40c8054a2f777522e65be921a77240c8042a19bff706fe5b7e3e7d0360cd82840bff3f4fe429bea0081560c0064419fd9157f8b9c797e92c20cc47fe2b7d5e6ee45bf0524010e0c0894299e7d037e4553bcbbc0989e0c40501bbbdc926f8daf53885e0a0c80971ffee559f5bf98ed54cf140c00581abbffac75b88b14d5e3780c5a046dd66fd7bfe5b7ca749df40c403672bbcfe47ee797860ded5e0cb5502efb7ee2ffc7bbdc27d0880c44ca08fbf7031ecd9321d21ef40cdc9806fefde36f0699ad1569420c22cb1bfbdc974fcb900ab601440c00cb1cfbdfd2f7d2730b0b46680c0b4203dfef309fe0adc121e2080c225829feeb901f25b926343bae0c624204dfff4875b69ceda4df4c0c499886ffe7301e8e8bf9ef0a260cdce408dbef829fe45337e98d860c010800ef76088d8015f3b2c84e0c755c3ecfc898f50fbcdb9344220c7c7d03459349337d01e4949da1b4ec0c7cf046ae6e4a90df3552070a5e0c7cf045d23fbba0951147986eca0c7536426e6ef2ef0b7d01c22fd2960cb8284e9db92d40552988334f200cb8024acdbfea90d13b545fe35e0cb8f04d5e48659d48b97c1096140c7c084f79df4402702126bf358a0cb8a74d4def66535e145638d12e0c543e4d8edfa2531b15a340eb800cb83e4eafbd9031291a8563e4780c54a74ef1c7300da79aa94bb67d050cb8f04eba6fb0325813871511b80ce20ff6fffd404ed58ecf264c8e0c7c0f1cb3fe1a36fb7187c379d00c7c3e52f6727d0261ca8bdd1361b80cb8d64d9a4fb1cfe0aadaaa7d05c40c2b2e44b2bfb9b4dcad9d7d0200280c7c3b47d5db803fc2aee71a77f00c7c1343b2bfa06ee6ad3228f10a0c7c3b4a76477fe7650b0c809ca80c54d74b92dbc327134514d6126e0c7c5f4a8f4f74efaaa5cd0a43bc0c7c104bb64ff5ce604fa2028b680c7cff4aaec7f7a9394cc4c599e60cb8ce52eeb553d215a6a466b4120c750f4fae5f9816c04a0a3f751e0c75e04f73c58e96bb4b925a4c680cb80f4b6e3fe1635614bbdeccbc0c7c3b4faf7e825e42d473ee76800ce298578ffcb61f0af936387bbe0cb800e39bf62410681583e0d2b20cb4987d05ff7f297bf69eaf4cd8b40cb57815bf7f300fcffe9fae966a0cb497acd75fd37f648d00d141a00cc48af9fffe1a3b979b8f8573e80c29bff1bf4b94c6fd7c3eec075e0c7cce1f5d5b5a4a2a3738393436383035303034323639322a303033392a303065352a4a58544b2c302c77617463685f375f32303232303532363039333935342c362c362c8f5cf9f34fa6edceb18c0ca4ce436e7d02d329de94b63eb11a0cb894438f44cf753dbc1a83b4560cb8e44391eff729d4155a231bf40cb59443f373b4288492cd6e38160c5a42049bfec8678ad42bce0c560cb12e39fec3d1fe24b5572ee0be0cb1ce35fe33688455aa74e3ffa40cb1d635df4b704160ae864a7d03440cb10f3267dbf4a21d540ca1051c0cb11337724f8747f5547d054e91660cb1a73692df964f3bbb0758d41a0cfe05b60c314460297eae4185f20cad673ceb6dfa05ddbe0278d5de5d")); + verifyPosition(decoder, buffer( "[3G*9031853319*004E*UD2,220322,055105,A,22.761162,N,114.360192,E,0,0,47,14,100,64,0,0,00000008,0,0]")); -- cgit v1.2.3 From bcd8d095de5e5b99dec3420ddd91419a0a3ba238 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 28 May 2022 11:29:12 -0700 Subject: Fix duplicated report devices --- src/main/java/org/traccar/reports/ReportUtils.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/reports/ReportUtils.java b/src/main/java/org/traccar/reports/ReportUtils.java index 58674beae..23646c4d6 100644 --- a/src/main/java/org/traccar/reports/ReportUtils.java +++ b/src/main/java/org/traccar/reports/ReportUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -48,6 +48,7 @@ import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -83,7 +84,7 @@ public final class ReportUtils { } public static Collection getDeviceList(Collection deviceIds, Collection groupIds) { - Collection result = new ArrayList<>(deviceIds); + Collection result = new LinkedHashSet<>(deviceIds); for (long groupId : groupIds) { result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); } -- cgit v1.2.3 From b9d7cbe6f15b471b0edff49870fef8190949ad09 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 28 May 2022 11:29:34 -0700 Subject: Ignore empty summary records --- src/main/java/org/traccar/reports/Summary.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java index 4924af062..f00b1ca57 100644 --- a/src/main/java/org/traccar/reports/Summary.java +++ b/src/main/java/org/traccar/reports/Summary.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -127,7 +127,12 @@ public final class Summary { ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(calculateSummaryResults(userId, deviceId, from, to, daily)); + Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); + for (SummaryReport summaryReport : deviceResults) { + if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { + result.add(summaryReport); + } + } } return result; } -- cgit v1.2.3 From b1a971eedb18a11af2cdc70ba5f8004bae89defd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 11:16:05 -0700 Subject: Remove unused interface --- .../java/org/traccar/database/DeviceManager.java | 4 +--- .../java/org/traccar/database/GroupsManager.java | 20 +--------------- .../org/traccar/database/ManagableObjects.java | 27 ---------------------- .../org/traccar/database/SimpleObjectManager.java | 5 +--- 4 files changed, 3 insertions(+), 53 deletions(-) delete mode 100644 src/main/java/org/traccar/database/ManagableObjects.java diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index a9b8454eb..a14fd7022 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -38,7 +38,7 @@ import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.storage.StorageException; -public class DeviceManager extends BaseObjectManager implements IdentityManager, ManagableObjects { +public class DeviceManager extends BaseObjectManager implements IdentityManager { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); @@ -162,7 +162,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return Context.getPermissionsManager().getDevicePermissions(userId); } - @Override public Set getUserItems(long userId) { if (Context.getPermissionsManager() != null) { Set result = new HashSet<>(); @@ -186,7 +185,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return result; } - @Override public Set getManagedItems(long userId) { Set result = new HashSet<>(getUserItems(userId)); for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { diff --git a/src/main/java/org/traccar/database/GroupsManager.java b/src/main/java/org/traccar/database/GroupsManager.java index dafddc0cc..9322dd80a 100644 --- a/src/main/java/org/traccar/database/GroupsManager.java +++ b/src/main/java/org/traccar/database/GroupsManager.java @@ -23,7 +23,7 @@ import org.traccar.Context; import org.traccar.model.Group; import org.traccar.storage.StorageException; -public class GroupsManager extends BaseObjectManager implements ManagableObjects { +public class GroupsManager extends BaseObjectManager { public GroupsManager(DataManager dataManager) { super(dataManager, Group.class); @@ -62,22 +62,4 @@ public class GroupsManager extends BaseObjectManager implements Managable super.updateItem(group); } - @Override - public Set getUserItems(long userId) { - if (Context.getPermissionsManager() != null) { - return Context.getPermissionsManager().getGroupPermissions(userId); - } else { - return new HashSet<>(); - } - } - - @Override - public Set getManagedItems(long userId) { - Set result = getUserItems(userId); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getUserItems(managedUserId)); - } - return result; - } - } diff --git a/src/main/java/org/traccar/database/ManagableObjects.java b/src/main/java/org/traccar/database/ManagableObjects.java deleted file mode 100644 index ec9549493..000000000 --- a/src/main/java/org/traccar/database/ManagableObjects.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.database; - -import java.util.Set; - -public interface ManagableObjects { - - Set getUserItems(long userId); - - Set getManagedItems(long userId); - -} diff --git a/src/main/java/org/traccar/database/SimpleObjectManager.java b/src/main/java/org/traccar/database/SimpleObjectManager.java index 78701720f..74bbc054f 100644 --- a/src/main/java/org/traccar/database/SimpleObjectManager.java +++ b/src/main/java/org/traccar/database/SimpleObjectManager.java @@ -29,8 +29,7 @@ import org.traccar.model.Permission; import org.traccar.model.User; import org.traccar.storage.StorageException; -public abstract class SimpleObjectManager extends BaseObjectManager - implements ManagableObjects { +public abstract class SimpleObjectManager extends BaseObjectManager { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleObjectManager.class); @@ -40,7 +39,6 @@ public abstract class SimpleObjectManager extends BaseObjec super(dataManager, baseClass); } - @Override public final Set getUserItems(long userId) { try { readLock(); @@ -55,7 +53,6 @@ public abstract class SimpleObjectManager extends BaseObjec } } - @Override public Set getManagedItems(long userId) { Set result = getUserItems(userId); for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { -- cgit v1.2.3 From 154ff3b2175e67b3fac531cb9c5c5c68880f5e12 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 11:49:39 -0700 Subject: Inject media manager --- build.gradle | 1 + src/main/java/org/traccar/BasePipelineFactory.java | 9 ++++---- src/main/java/org/traccar/BaseProtocolDecoder.java | 14 +++++++++++ src/main/java/org/traccar/Context.java | 12 +--------- src/main/java/org/traccar/MainEventHandler.java | 2 ++ .../java/org/traccar/database/GroupsManager.java | 3 +-- .../java/org/traccar/database/MediaManager.java | 12 ++++++---- .../traccar/protocol/AtrackProtocolDecoder.java | 2 +- .../traccar/protocol/DualcamProtocolDecoder.java | 3 +-- .../traccar/protocol/FifotrackProtocolDecoder.java | 3 +-- .../traccar/protocol/GalileoProtocolDecoder.java | 2 +- .../traccar/protocol/Gps103ProtocolDecoder.java | 3 +-- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 6 ++--- .../traccar/protocol/MeiligaoProtocolDecoder.java | 2 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 2 +- .../org/traccar/protocol/Pt502ProtocolDecoder.java | 2 +- .../traccar/protocol/RuptelaProtocolDecoder.java | 3 +-- .../traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- .../org/traccar/protocol/WatchProtocolDecoder.java | 7 +++--- src/test/java/org/traccar/BaseTest.java | 27 +--------------------- .../traccar/protocol/WatchProtocolDecoderTest.java | 18 +++++++-------- 21 files changed, 57 insertions(+), 78 deletions(-) diff --git a/build.gradle b/build.gradle index 25c8a32e3..de8c86712 100644 --- a/build.gradle +++ b/build.gradle @@ -83,6 +83,7 @@ dependencies { implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.141" testImplementation "junit:junit:4.13.2" + testImplementation "org.mockito:mockito-core:3.+" } task copyDependencies(type: Copy) { diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 89ef76a80..1f383f211 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -109,7 +109,9 @@ public abstract class BasePipelineFactory extends ChannelInitializer { pipeline.addLast(new StandardLoggingHandler(protocol)); addProtocolHandlers(handler -> { - if (!(handler instanceof BaseProtocolDecoder || handler instanceof BaseProtocolEncoder)) { + if (handler instanceof BaseProtocolDecoder || handler instanceof BaseProtocolEncoder) { + Main.getInjector().injectMembers(handler); + } else { if (handler instanceof ChannelInboundHandler) { handler = new WrapperInboundHandler((ChannelInboundHandler) handler); } else { @@ -144,9 +146,8 @@ public abstract class BasePipelineFactory extends ChannelInitializer { AlertEventHandler.class, IgnitionEventHandler.class, MaintenanceEventHandler.class, - DriverEventHandler.class); - - pipeline.addLast(new MainEventHandler()); + DriverEventHandler.class, + MainEventHandler.class); } } diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index a40756796..505e7926f 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -15,6 +15,8 @@ */ package org.traccar; +import com.google.inject.Inject; +import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import io.netty.channel.socket.DatagramChannel; import io.netty.handler.codec.http.HttpRequestDecoder; @@ -25,6 +27,7 @@ import org.traccar.config.Keys; import org.traccar.database.CommandsManager; import org.traccar.database.ConnectionManager; import org.traccar.database.IdentityManager; +import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.helper.UnitsConverter; import org.traccar.model.Command; @@ -53,11 +56,22 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private final StatisticsManager statisticsManager; private final Protocol protocol; + private MediaManager mediaManager; + public BaseProtocolDecoder(Protocol protocol) { this.protocol = protocol; statisticsManager = Main.getInjector() != null ? Main.getInjector().getInstance(StatisticsManager.class) : null; } + @Inject + public void setMediaManager(MediaManager mediaManager) { + this.mediaManager = mediaManager; + } + + public String writeMediaFile(String uniqueId, ByteBuf buf, String extension) { + return mediaManager.writeFile(uniqueId, buf, extension); + } + public String getProtocolName() { return protocol != null ? protocol.getName() : PROTOCOL_UNKNOWN; } diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index ee14f8a1a..237a34624 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -37,7 +37,6 @@ import org.traccar.database.IdentityManager; import org.traccar.database.LdapProvider; import org.traccar.database.MailManager; import org.traccar.database.MaintenancesManager; -import org.traccar.database.MediaManager; import org.traccar.database.NotificationManager; import org.traccar.database.OrderManager; import org.traccar.database.PermissionsManager; @@ -114,12 +113,6 @@ public final class Context { return mailManager; } - private static MediaManager mediaManager; - - public static MediaManager getMediaManager() { - return mediaManager; - } - private static UsersManager usersManager; public static UsersManager getUsersManager() { @@ -313,8 +306,6 @@ public final class Context { mailManager = new MailManager(); - mediaManager = new MediaManager(config.getString(Keys.MEDIA_PATH)); - if (dataManager != null) { usersManager = new UsersManager(dataManager); groupsManager = new GroupsManager(dataManager); @@ -390,13 +381,12 @@ public final class Context { velocityEngine.init(velocityProperties); } - public static void init(IdentityManager testIdentityManager, MediaManager testMediaManager) { + public static void init(IdentityManager testIdentityManager) { config = new Config(); objectMapper = new ObjectMapper(); objectMapper.registerModule(new JSR353Module()); client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); identityManager = testIdentityManager; - mediaManager = testMediaManager; } public static BaseObjectManager getManager(Class clazz) { diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index f1f2527bc..91706222a 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -30,6 +30,7 @@ import org.traccar.helper.NetworkUtil; import org.traccar.model.Position; import org.traccar.storage.StorageException; +import javax.inject.Inject; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; @@ -42,6 +43,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Set connectionlessProtocols = new HashSet<>(); private final Set logAttributes = new LinkedHashSet<>(); + @Inject public MainEventHandler() { String connectionlessProtocolList = Context.getConfig().getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { diff --git a/src/main/java/org/traccar/database/GroupsManager.java b/src/main/java/org/traccar/database/GroupsManager.java index 9322dd80a..4df848042 100644 --- a/src/main/java/org/traccar/database/GroupsManager.java +++ b/src/main/java/org/traccar/database/GroupsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +19,6 @@ package org.traccar.database; import java.util.HashSet; import java.util.Set; -import org.traccar.Context; import org.traccar.model.Group; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/database/MediaManager.java b/src/main/java/org/traccar/database/MediaManager.java index edade5766..5f3fdcdf7 100644 --- a/src/main/java/org/traccar/database/MediaManager.java +++ b/src/main/java/org/traccar/database/MediaManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@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,7 +18,10 @@ package org.traccar.database; import io.netty.buffer.ByteBuf; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import javax.inject.Inject; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -34,10 +37,11 @@ public class MediaManager { private static final Logger LOGGER = LoggerFactory.getLogger(MediaManager.class); - private String path; + private final String path; - public MediaManager(String path) { - this.path = path; + @Inject + public MediaManager(Config config) { + this.path = config.getString(Keys.MEDIA_PATH); } private File createFile(String uniqueId, String name) throws IOException { diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 186b81470..247a1b696 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -626,7 +626,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, new Date(time * 1000)); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(String.valueOf(id), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(String.valueOf(id), photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index c64b8171f..3c15d41eb 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; 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; @@ -98,7 +97,7 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); } finally { photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 5f9326a61..53f35c3cd 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; 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; @@ -381,7 +380,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(getDeviceSession(channel, remoteAddress, imei).getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); photo.release(); photo = null; return position; diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index f29fb9850..eb553c5a9 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -329,7 +329,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index d74f19179..d5aa45b9c 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; 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; @@ -361,7 +360,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); } finally { photoPackets = 0; photo.release(); diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 89931f614..832645374 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1028,8 +1028,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { sendPhotoRequest(channel, pictureId); } else { Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); - position.set( - Position.KEY_IMAGE, Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); photos.remove(pictureId).release(); } @@ -1265,8 +1264,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, new Date(timestamp)); Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); - position.set(Position.KEY_IMAGE, - Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); photos.remove(mediaId).release(); } } diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index d38e5d1c3..a25cab06f 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -472,7 +472,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); ByteBuf photo = photos.remove(imageIndex); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); } finally { photo.release(); } diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 013e297c0..6fed56fb6 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -589,7 +589,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java index ff92b51f1..5e24cacdc 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -182,7 +182,7 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 5a0383358..7abb52bd0 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; 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; @@ -298,7 +297,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg")); photo.release(); photo = null; return position; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index f83a49941..61a61b900 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -148,7 +148,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); photos.remove(photoId); try { - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); } finally { photo.release(); } diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 420866578..3967fb804 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; 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; @@ -313,7 +312,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { int timeIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); buf.readerIndex(timeIndex + 12 + 2); - position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(id, buf, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(id, buf, "jpg")); return position; @@ -339,7 +338,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_AUDIO, Context.getMediaManager().writeFile(id, audio, "amr")); + position.set(Position.KEY_AUDIO, writeMediaFile(id, audio, "amr")); audio.release(); audio = null; return position; @@ -356,7 +355,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_AUDIO, Context.getMediaManager().writeFile(id, buf, "amr")); + position.set(Position.KEY_AUDIO, writeMediaFile(id, buf, "amr")); return position; diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 0b2c616ce..1dddbb03b 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,34 +1,9 @@ package org.traccar; -import io.netty.buffer.ByteBuf; -import org.traccar.database.MediaManager; - -import java.util.HashMap; -import java.util.Map; - public class BaseTest { - public static class MockMediaManager extends MediaManager { - Map files = new HashMap<>(); - - MockMediaManager() { - super(""); - } - - @Override - public String writeFile(String uniqueId, ByteBuf buf, String extension) { - String fileName = uniqueId + "/mock." + extension; - files.put(fileName, buf); - return fileName; - } - - public ByteBuf readFile(String fileName) { - return files.get(fileName); - } - } - static { - Context.init(new TestIdentityManager(), new MockMediaManager()); + Context.init(new TestIdentityManager()); } } diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index ef6c33da9..50baaa81a 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -1,12 +1,11 @@ package org.traccar.protocol; -import io.netty.buffer.ByteBuf; import org.junit.Test; -import org.traccar.Context; import org.traccar.ProtocolTest; +import org.traccar.database.MediaManager; import org.traccar.model.Position; -import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; public class WatchProtocolDecoderTest extends ProtocolTest { @@ -148,14 +147,15 @@ public class WatchProtocolDecoderTest extends ProtocolTest { var decoder = new WatchProtocolDecoder(null); - verifyNull(decoder.decode(null, null, buffer("[CS*1234567890*0004*TK,1]"))); + var mediaManager = mock(MediaManager.class); + when(mediaManager.writeFile(any(), any(), any())).thenReturn("mock.amr"); + decoder.setMediaManager(mediaManager); - ByteBuf data = binary("7d5b5d2c2aff"); + verifyAttribute(decoder, concatenateBuffers( + buffer("[CS*1234567890*000e*TK,#!AMR"), binary("7d5b5d2c2aff"), buffer("]")), + Position.KEY_AUDIO, "mock.amr"); - Object decodedObject = decoder.decode(null, null, concatenateBuffers(buffer("[CS*1234567890*000e*TK,#!AMR"), data.resetReaderIndex(), buffer("]"))); - assertEquals("1234567890/mock.amr", ((Position) decodedObject).getAttributes().get("audio")); - - verifyFrame(concatenateBuffers(buffer("#!AMR"), data.resetReaderIndex()), ((MockMediaManager) Context.getMediaManager()).readFile("1234567890/mock.amr")); + verify(mediaManager).writeFile(any(), any(), any()); } -- cgit v1.2.3 From ce661ec77a957b70c15509c6801e6f34b32ad11d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 13:12:37 -0700 Subject: Improve dependency injection --- setup/default.xml | 2 - src/main/java/org/traccar/MainModule.java | 213 ++------------------- src/main/java/org/traccar/WebDataHandler.java | 6 +- src/main/java/org/traccar/config/Keys.java | 14 -- .../org/traccar/database/ConnectionManager.java | 9 +- .../traccar/handler/ComputedAttributesHandler.java | 5 +- .../org/traccar/handler/CopyAttributesHandler.java | 30 ++- .../org/traccar/handler/DefaultDataHandler.java | 5 +- .../java/org/traccar/handler/DistanceHandler.java | 4 +- .../org/traccar/handler/EngineHoursHandler.java | 5 +- .../java/org/traccar/handler/FilterHandler.java | 67 +++---- .../org/traccar/handler/HemisphereHandler.java | 5 +- .../java/org/traccar/handler/MotionHandler.java | 12 +- .../org/traccar/handler/RemoteAddressHandler.java | 24 ++- .../org/traccar/handler/SpeedLimitHandler.java | 5 +- src/main/java/org/traccar/handler/TimeHandler.java | 14 +- .../traccar/handler/events/AlertEventHandler.java | 5 +- .../handler/events/BehaviorEventHandler.java | 4 +- .../handler/events/CommandResultEventHandler.java | 8 +- .../traccar/handler/events/DriverEventHandler.java | 5 +- .../handler/events/FuelDropEventHandler.java | 4 +- .../handler/events/GeofenceEventHandler.java | 5 +- .../handler/events/IgnitionEventHandler.java | 5 +- .../handler/events/MaintenanceEventHandler.java | 5 +- .../traccar/handler/events/MotionEventHandler.java | 5 +- .../handler/events/OverspeedEventHandler.java | 5 +- .../org/traccar/reports/model/TripsConfig.java | 47 +---- src/test/java/org/traccar/TestIdentityManager.java | 3 - .../org/traccar/handler/FilterHandlerTest.java | 75 ++++---- .../org/traccar/handler/MotionHandlerTest.java | 7 +- 30 files changed, 232 insertions(+), 371 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index 1f89ae3d8..dea638d7a 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -30,8 +30,6 @@ 86400 true - true - true ./media diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 79cfcc0a8..60b5854fd 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -18,7 +18,10 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.AbstractModule; import com.google.inject.Provides; +import com.google.inject.Scopes; import com.google.inject.Singleton; +import io.netty.util.HashedWheelTimer; +import io.netty.util.Timer; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.AttributesManager; @@ -43,51 +46,35 @@ import org.traccar.geocoder.GoogleGeocoder; import org.traccar.geocoder.HereGeocoder; import org.traccar.geocoder.MapQuestGeocoder; import org.traccar.geocoder.MapTilerGeocoder; +import org.traccar.geocoder.MapboxGeocoder; import org.traccar.geocoder.MapmyIndiaGeocoder; import org.traccar.geocoder.NominatimGeocoder; import org.traccar.geocoder.OpenCageGeocoder; import org.traccar.geocoder.PositionStackGeocoder; import org.traccar.geocoder.TomTomGeocoder; -import org.traccar.geocoder.MapboxGeocoder; import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; import org.traccar.geolocation.MozillaGeolocationProvider; import org.traccar.geolocation.OpenCellIdGeolocationProvider; import org.traccar.geolocation.UnwiredGeolocationProvider; -import org.traccar.handler.ComputedAttributesHandler; -import org.traccar.handler.CopyAttributesHandler; -import org.traccar.handler.DefaultDataHandler; -import org.traccar.handler.DistanceHandler; -import org.traccar.handler.EngineHoursHandler; -import org.traccar.handler.FilterHandler; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; -import org.traccar.handler.HemisphereHandler; -import org.traccar.handler.MotionHandler; -import org.traccar.handler.RemoteAddressHandler; import org.traccar.handler.SpeedLimitHandler; -import org.traccar.handler.TimeHandler; -import org.traccar.handler.events.AlertEventHandler; -import org.traccar.handler.events.BehaviorEventHandler; -import org.traccar.handler.events.CommandResultEventHandler; -import org.traccar.handler.events.DriverEventHandler; -import org.traccar.handler.events.FuelDropEventHandler; -import org.traccar.handler.events.GeofenceEventHandler; -import org.traccar.handler.events.IgnitionEventHandler; -import org.traccar.handler.events.MaintenanceEventHandler; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.handler.events.OverspeedEventHandler; import org.traccar.reports.model.TripsConfig; - -import javax.annotation.Nullable; -import javax.ws.rs.client.Client; -import io.netty.util.Timer; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.Storage; +import javax.annotation.Nullable; +import javax.ws.rs.client.Client; + public class MainModule extends AbstractModule { + @Override + protected void configure() { + bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); + } + @Provides public static ObjectMapper provideObjectMapper() { return Context.getObjectMapper(); @@ -153,13 +140,6 @@ public class MainModule extends AbstractModule { return Context.getMaintenancesManager(); } - @Singleton - @Provides - public static StatisticsManager provideStatisticsManager( - Config config, DataManager dataManager, Client client, ObjectMapper objectMapper) { - return new StatisticsManager(config, dataManager, client, objectMapper); - } - @Singleton @Provides public static Geocoder provideGeocoder(Config config) { @@ -249,50 +229,6 @@ public class MainModule extends AbstractModule { return null; } - @Singleton - @Provides - public static DistanceHandler provideDistanceHandler(Config config, IdentityManager identityManager) { - return new DistanceHandler(config, identityManager); - } - - @Singleton - @Provides - public static FilterHandler provideFilterHandler(Config config) { - if (config.getBoolean(Keys.FILTER_ENABLE)) { - return new FilterHandler(config); - } - return null; - } - - @Singleton - @Provides - public static HemisphereHandler provideHemisphereHandler(Config config) { - if (config.hasKey(Keys.LOCATION_LATITUDE_HEMISPHERE) || config.hasKey(Keys.LOCATION_LONGITUDE_HEMISPHERE)) { - return new HemisphereHandler(config); - } - return null; - } - - @Singleton - @Provides - public static RemoteAddressHandler provideRemoteAddressHandler(Config config) { - if (config.getBoolean(Keys.PROCESSING_REMOTE_ADDRESS_ENABLE)) { - return new RemoteAddressHandler(); - } - return null; - } - - @Singleton - @Provides - public static WebDataHandler provideWebDataHandler( - Config config, IdentityManager identityManager, ObjectMapper objectMapper, Client client) { - if (config.hasKey(Keys.FORWARD_URL)) { - return new WebDataHandler(config, identityManager, objectMapper, client); - } - return null; - } - - @Singleton @Provides public static GeolocationHandler provideGeolocationHandler( Config config, @Nullable GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) { @@ -302,7 +238,6 @@ public class MainModule extends AbstractModule { return null; } - @Singleton @Provides public static GeocoderHandler provideGeocoderHandler( Config config, @Nullable Geocoder geocoder, IdentityManager identityManager) { @@ -312,7 +247,6 @@ public class MainModule extends AbstractModule { return null; } - @Singleton @Provides public static SpeedLimitHandler provideSpeedLimitHandler(@Nullable SpeedLimitProvider speedLimitProvider) { if (speedLimitProvider != null) { @@ -321,127 +255,4 @@ public class MainModule extends AbstractModule { return null; } - @Singleton - @Provides - public static MotionHandler provideMotionHandler(TripsConfig tripsConfig) { - return new MotionHandler(tripsConfig.getSpeedThreshold()); - } - - @Singleton - @Provides - public static EngineHoursHandler provideEngineHoursHandler(Config config, IdentityManager identityManager) { - if (config.getBoolean(Keys.PROCESSING_ENGINE_HOURS_ENABLE)) { - return new EngineHoursHandler(identityManager); - } - return null; - } - - @Singleton - @Provides - public static CopyAttributesHandler provideCopyAttributesHandler(Config config, IdentityManager identityManager) { - if (config.getBoolean(Keys.PROCESSING_COPY_ATTRIBUTES_ENABLE)) { - return new CopyAttributesHandler(identityManager); - } - return null; - } - - @Singleton - @Provides - public static ComputedAttributesHandler provideComputedAttributesHandler( - Config config, IdentityManager identityManager, AttributesManager attributesManager) { - if (config.getBoolean(Keys.PROCESSING_COMPUTED_ATTRIBUTES_ENABLE)) { - return new ComputedAttributesHandler(config, identityManager, attributesManager); - } - return null; - } - - @Singleton - @Provides - public static TimeHandler provideTimeHandler(Config config) { - if (config.hasKey(Keys.TIME_OVERRIDE)) { - return new TimeHandler(config); - } - return null; - } - - @Singleton - @Provides - public static DefaultDataHandler provideDefaultDataHandler(@Nullable DataManager dataManager) { - if (dataManager != null) { - return new DefaultDataHandler(dataManager); - } - return null; - } - - @Singleton - @Provides - public static CommandResultEventHandler provideCommandResultEventHandler() { - return new CommandResultEventHandler(); - } - - @Singleton - @Provides - public static OverspeedEventHandler provideOverspeedEventHandler( - Config config, DeviceManager deviceManager, GeofenceManager geofenceManager) { - return new OverspeedEventHandler(config, deviceManager, geofenceManager); - } - - @Singleton - @Provides - public static BehaviorEventHandler provideBehaviorEventHandler(Config config, IdentityManager identityManager) { - return new BehaviorEventHandler(config, identityManager); - } - - @Singleton - @Provides - public static FuelDropEventHandler provideFuelDropEventHandler(IdentityManager identityManager) { - return new FuelDropEventHandler(identityManager); - } - - @Singleton - @Provides - public static MotionEventHandler provideMotionEventHandler( - IdentityManager identityManager, DeviceManager deviceManager, TripsConfig tripsConfig) { - return new MotionEventHandler(identityManager, deviceManager, tripsConfig); - } - - @Singleton - @Provides - public static GeofenceEventHandler provideGeofenceEventHandler( - IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager, - ConnectionManager connectionManager) { - return new GeofenceEventHandler(identityManager, geofenceManager, calendarManager, connectionManager); - } - - @Singleton - @Provides - public static AlertEventHandler provideAlertEventHandler(Config config, IdentityManager identityManager) { - return new AlertEventHandler(config, identityManager); - } - - @Singleton - @Provides - public static IgnitionEventHandler provideIgnitionEventHandler(IdentityManager identityManager) { - return new IgnitionEventHandler(identityManager); - } - - @Singleton - @Provides - public static MaintenanceEventHandler provideMaintenanceEventHandler( - IdentityManager identityManager, MaintenancesManager maintenancesManager) { - return new MaintenanceEventHandler(identityManager, maintenancesManager); - } - - @Singleton - @Provides - public static DriverEventHandler provideDriverEventHandler(IdentityManager identityManager) { - return new DriverEventHandler(identityManager); - } - - @Singleton - @Provides - public static Timer provideTimer() { - return GlobalTimer.getTimer(); - } - } diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index 678096d34..2c0aa0f8e 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -287,8 +287,10 @@ public class WebDataHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - AsyncRequestAndCallback request = new AsyncRequestAndCallback(position); - request.send(); + if (url != null) { + AsyncRequestAndCallback request = new AsyncRequestAndCallback(position); + request.send(); + } return position; } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index bb3ea393a..eebdf7172 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1021,13 +1021,6 @@ public final class Keys { "processing.remoteAddress.enable", Collections.singletonList(KeyType.GLOBAL)); - /** - * Enable engine hours calculation on the server side. It uses ignition value to determine engine state. - */ - public static final ConfigKey PROCESSING_ENGINE_HOURS_ENABLE = new ConfigKey<>( - "processing.engineHours.enable", - Collections.singletonList(KeyType.GLOBAL)); - /** * Enable copying of missing attributes from last position to the current one. Might be useful if device doesn't * send some values in every message. @@ -1036,13 +1029,6 @@ public final class Keys { "processing.copyAttributes.enable", Collections.singletonList(KeyType.GLOBAL)); - /** - * Enable computed attributes processing. - */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_ENABLE = new ConfigKey<>( - "processing.computedAttributes.enable", - Collections.singletonList(KeyType.GLOBAL)); - /** * Enable computed attributes processing. */ diff --git a/src/main/java/org/traccar/database/ConnectionManager.java b/src/main/java/org/traccar/database/ConnectionManager.java index 359061f00..f0e40f631 100644 --- a/src/main/java/org/traccar/database/ConnectionManager.java +++ b/src/main/java/org/traccar/database/ConnectionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,10 +17,10 @@ package org.traccar.database; import io.netty.channel.Channel; import io.netty.util.Timeout; +import io.netty.util.Timer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.GlobalTimer; import org.traccar.Main; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -52,9 +52,12 @@ public class ConnectionManager { private final Map> listeners = new ConcurrentHashMap<>(); private final Map timeouts = new ConcurrentHashMap<>(); + private final Timer timer; + public ConnectionManager() { deviceTimeout = Context.getConfig().getLong(Keys.STATUS_TIMEOUT) * 1000; updateDeviceState = Context.getConfig().getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); + timer = Main.getInjector().getInstance(Timer.class); } public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { @@ -118,7 +121,7 @@ public class ConnectionManager { } if (status.equals(Device.STATUS_ONLINE)) { - timeouts.put(deviceId, GlobalTimer.getTimer().newTimeout(timeout1 -> { + timeouts.put(deviceId, timer.newTimeout(timeout1 -> { if (!timeout1.isCancelled()) { updateDevice(deviceId, Device.STATUS_UNKNOWN, null); } diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 153da29b9..9dc170909 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,6 +40,8 @@ import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class ComputedAttributesHandler extends BaseDataHandler { @@ -52,6 +54,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private final boolean includeDeviceAttributes; + @Inject public ComputedAttributesHandler( Config config, IdentityManager identityManager, AttributesManager attributesManager) { this.identityManager = identityManager; diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index f386116b0..8285dcc5d 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,27 +18,37 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.database.IdentityManager; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class CopyAttributesHandler extends BaseDataHandler { - private IdentityManager identityManager; + private final boolean enabled; + private final IdentityManager identityManager; - public CopyAttributesHandler(IdentityManager identityManager) { + @Inject + public CopyAttributesHandler(Config config, IdentityManager identityManager) { + enabled = config.getBoolean(Keys.PROCESSING_COPY_ATTRIBUTES_ENABLE); this.identityManager = identityManager; } @Override protected Position handlePosition(Position position) { - String attributesString = identityManager.lookupAttributeString( - position.getDeviceId(), "processing.copyAttributes", "", false, true); - Position last = identityManager.getLastPosition(position.getDeviceId()); - if (last != null) { - for (String attribute : attributesString.split("[ ,]")) { - if (last.getAttributes().containsKey(attribute) && !position.getAttributes().containsKey(attribute)) { - position.getAttributes().put(attribute, last.getAttributes().get(attribute)); + if (enabled) { + String attributesString = identityManager.lookupAttributeString( + position.getDeviceId(), "processing.copyAttributes", "", false, true); + Position last = identityManager.getLastPosition(position.getDeviceId()); + if (last != null) { + for (String attribute : attributesString.split("[ ,]")) { + if (last.getAttributes().containsKey(attribute) + && !position.getAttributes().containsKey(attribute)) { + position.getAttributes().put(attribute, last.getAttributes().get(attribute)); + } } } } diff --git a/src/main/java/org/traccar/handler/DefaultDataHandler.java b/src/main/java/org/traccar/handler/DefaultDataHandler.java index 9d8ea044d..c2adfd799 100644 --- a/src/main/java/org/traccar/handler/DefaultDataHandler.java +++ b/src/main/java/org/traccar/handler/DefaultDataHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,8 @@ import org.traccar.BaseDataHandler; import org.traccar.database.DataManager; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class DefaultDataHandler extends BaseDataHandler { @@ -29,6 +31,7 @@ public class DefaultDataHandler extends BaseDataHandler { private final DataManager dataManager; + @Inject public DefaultDataHandler(DataManager dataManager) { this.dataManager = dataManager; } diff --git a/src/main/java/org/traccar/handler/DistanceHandler.java b/src/main/java/org/traccar/handler/DistanceHandler.java index 1e7e444f6..08c8c068d 100644 --- a/src/main/java/org/traccar/handler/DistanceHandler.java +++ b/src/main/java/org/traccar/handler/DistanceHandler.java @@ -1,6 +1,6 @@ /* + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2015 Amila Silva - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.traccar.database.IdentityManager; import org.traccar.helper.DistanceCalculator; import org.traccar.model.Position; +import javax.inject.Inject; import java.math.BigDecimal; import java.math.RoundingMode; @@ -36,6 +37,7 @@ public class DistanceHandler extends BaseDataHandler { private final int coordinatesMinError; private final int coordinatesMaxError; + @Inject public DistanceHandler(Config config, IdentityManager identityManager) { this.identityManager = identityManager; this.filter = config.getBoolean(Keys.COORDINATES_FILTER); diff --git a/src/main/java/org/traccar/handler/EngineHoursHandler.java b/src/main/java/org/traccar/handler/EngineHoursHandler.java index 92da84e6b..be2a46ade 100644 --- a/src/main/java/org/traccar/handler/EngineHoursHandler.java +++ b/src/main/java/org/traccar/handler/EngineHoursHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,11 +21,14 @@ import org.traccar.BaseDataHandler; import org.traccar.database.IdentityManager; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class EngineHoursHandler extends BaseDataHandler { private final IdentityManager identityManager; + @Inject public EngineHoursHandler(IdentityManager identityManager) { this.identityManager = identityManager; } diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index e576a26b8..0511ec98b 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2022 Anton Tananaev (anton@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,13 +19,15 @@ import io.netty.channel.ChannelHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.DataManager; +import org.traccar.database.IdentityManager; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import org.traccar.storage.StorageException; +import javax.inject.Inject; import java.util.Date; @ChannelHandler.Sharable @@ -33,21 +35,27 @@ public class FilterHandler extends BaseDataHandler { private static final Logger LOGGER = LoggerFactory.getLogger(FilterHandler.class); - private boolean filterInvalid; - private boolean filterZero; - private boolean filterDuplicate; - private long filterFuture; - private boolean filterApproximate; - private int filterAccuracy; - private boolean filterStatic; - private int filterDistance; - private int filterMaxSpeed; - private long filterMinPeriod; - private boolean filterRelative; - private long skipLimit; - private boolean skipAttributes; - - public FilterHandler(Config config) { + private final boolean enabled; + private final boolean filterInvalid; + private final boolean filterZero; + private final boolean filterDuplicate; + private final long filterFuture; + private final boolean filterApproximate; + private final int filterAccuracy; + private final boolean filterStatic; + private final int filterDistance; + private final int filterMaxSpeed; + private final long filterMinPeriod; + private final boolean filterRelative; + private final long skipLimit; + private final boolean skipAttributes; + + private final IdentityManager identityManager; + private final DataManager dataManager; + + @Inject + public FilterHandler(Config config, IdentityManager identityManager, DataManager dataManager) { + enabled = config.getBoolean(Keys.FILTER_ENABLE); filterInvalid = config.getBoolean(Keys.FILTER_INVALID); filterZero = config.getBoolean(Keys.FILTER_ZERO); filterDuplicate = config.getBoolean(Keys.FILTER_DUPLICATE); @@ -57,10 +65,12 @@ public class FilterHandler extends BaseDataHandler { filterStatic = config.getBoolean(Keys.FILTER_STATIC); filterDistance = config.getInteger(Keys.FILTER_DISTANCE); filterMaxSpeed = config.getInteger(Keys.FILTER_MAX_SPEED); - filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000; + filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000L; filterRelative = config.getBoolean(Keys.FILTER_RELATIVE); skipLimit = config.getLong(Keys.FILTER_SKIP_LIMIT) * 1000; skipAttributes = config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE); + this.identityManager = identityManager; + this.dataManager = dataManager; } private boolean filterInvalid(Position position) { @@ -134,7 +144,7 @@ public class FilterHandler extends BaseDataHandler { private boolean skipAttributes(Position position) { if (skipAttributes) { - String attributesString = Context.getIdentityManager().lookupAttributeString( + String attributesString = identityManager.lookupAttributeString( position.getDeviceId(), "filter.skipAttributes", "", false, true); for (String attribute : attributesString.split("[ ,]")) { if (position.getAttributes().containsKey(attribute)) { @@ -173,7 +183,7 @@ public class FilterHandler extends BaseDataHandler { if (filterRelative) { try { Date newFixTime = position.getFixTime(); - preceding = Context.getDataManager().getPrecedingPosition(deviceId, newFixTime); + preceding = dataManager.getPrecedingPosition(deviceId, newFixTime); } catch (StorageException e) { LOGGER.warn("Error retrieving preceding position; fallbacking to last received position.", e); preceding = getLastReceivedPosition(deviceId); @@ -199,14 +209,8 @@ public class FilterHandler extends BaseDataHandler { } if (filterType.length() > 0) { - - StringBuilder message = new StringBuilder(); - message.append("Position filtered by "); - message.append(filterType.toString()); - message.append("filters from device: "); - message.append(Context.getIdentityManager().getById(deviceId).getUniqueId()); - - LOGGER.info(message.toString()); + String uniqueId = identityManager.getById(deviceId).getUniqueId(); + LOGGER.info("Position filtered by {}filters from device: {}", filterType, uniqueId); return true; } @@ -214,15 +218,12 @@ public class FilterHandler extends BaseDataHandler { } private Position getLastReceivedPosition(long deviceId) { - if (Context.getIdentityManager() != null) { - return Context.getIdentityManager().getLastPosition(deviceId); - } - return null; + return identityManager.getLastPosition(deviceId); } @Override protected Position handlePosition(Position position) { - if (filter(position)) { + if (enabled && filter(position)) { return null; } return position; diff --git a/src/main/java/org/traccar/handler/HemisphereHandler.java b/src/main/java/org/traccar/handler/HemisphereHandler.java index aff3d8a64..2e3ed9d91 100644 --- a/src/main/java/org/traccar/handler/HemisphereHandler.java +++ b/src/main/java/org/traccar/handler/HemisphereHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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,15 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class HemisphereHandler extends BaseDataHandler { private int latitudeFactor; private int longitudeFactor; + @Inject public HemisphereHandler(Config config) { String latitudeHemisphere = config.getString(Keys.LOCATION_LATITUDE_HEMISPHERE); if (latitudeHemisphere != null) { diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java index e8051dd75..864eb455d 100644 --- a/src/main/java/org/traccar/handler/MotionHandler.java +++ b/src/main/java/org/traccar/handler/MotionHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,14 +19,18 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; import org.traccar.model.Position; +import org.traccar.reports.model.TripsConfig; + +import javax.inject.Inject; @ChannelHandler.Sharable public class MotionHandler extends BaseDataHandler { - private double speedThreshold; + private final double speedThreshold; - public MotionHandler(double speedThreshold) { - this.speedThreshold = speedThreshold; + @Inject + public MotionHandler(TripsConfig tripsConfig) { + speedThreshold = tripsConfig.getSpeedThreshold(); } @Override diff --git a/src/main/java/org/traccar/handler/RemoteAddressHandler.java b/src/main/java/org/traccar/handler/RemoteAddressHandler.java index c09b8c39a..809f67ca2 100644 --- a/src/main/java/org/traccar/handler/RemoteAddressHandler.java +++ b/src/main/java/org/traccar/handler/RemoteAddressHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,22 +18,34 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.model.Position; +import javax.inject.Inject; import java.net.InetSocketAddress; @ChannelHandler.Sharable public class RemoteAddressHandler extends ChannelInboundHandlerAdapter { + private final boolean enabled; + + @Inject + public RemoteAddressHandler(Config config) { + enabled = config.getBoolean(Keys.PROCESSING_REMOTE_ADDRESS_ENABLE); + } + @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { - InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); - String hostAddress = remoteAddress != null ? remoteAddress.getAddress().getHostAddress() : null; + if (enabled) { + InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); + String hostAddress = remoteAddress != null ? remoteAddress.getAddress().getHostAddress() : null; - if (msg instanceof Position) { - Position position = (Position) msg; - position.set(Position.KEY_IP, hostAddress); + if (msg instanceof Position) { + Position position = (Position) msg; + position.set(Position.KEY_IP, hostAddress); + } } ctx.fireChannelRead(msg); diff --git a/src/main/java/org/traccar/handler/SpeedLimitHandler.java b/src/main/java/org/traccar/handler/SpeedLimitHandler.java index 65f2c9cfe..0469b9f16 100644 --- a/src/main/java/org/traccar/handler/SpeedLimitHandler.java +++ b/src/main/java/org/traccar/handler/SpeedLimitHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@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,8 @@ import org.slf4j.LoggerFactory; import org.traccar.model.Position; import org.traccar.speedlimit.SpeedLimitProvider; +import javax.inject.Inject; + @ChannelHandler.Sharable public class SpeedLimitHandler extends ChannelInboundHandlerAdapter { @@ -30,6 +32,7 @@ public class SpeedLimitHandler extends ChannelInboundHandlerAdapter { private final SpeedLimitProvider speedLimitProvider; + @Inject public SpeedLimitHandler(SpeedLimitProvider speedLimitProvider) { this.speedLimitProvider = speedLimitProvider; } diff --git a/src/main/java/org/traccar/handler/TimeHandler.java b/src/main/java/org/traccar/handler/TimeHandler.java index 822c22a0a..c7e5e6e5c 100644 --- a/src/main/java/org/traccar/handler/TimeHandler.java +++ b/src/main/java/org/traccar/handler/TimeHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Position; +import javax.inject.Inject; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -31,11 +32,18 @@ import java.util.Set; @ChannelHandler.Sharable public class TimeHandler extends ChannelInboundHandlerAdapter { + private final boolean enabled; private final boolean useServerTime; private final Set protocols; + @Inject public TimeHandler(Config config) { - useServerTime = config.getString(Keys.TIME_OVERRIDE).equalsIgnoreCase("serverTime"); + enabled = config.hasKey(Keys.TIME_OVERRIDE); + if (enabled) { + useServerTime = config.getString(Keys.TIME_OVERRIDE).equalsIgnoreCase("serverTime"); + } else { + useServerTime = false; + } String protocolList = Context.getConfig().getString(Keys.TIME_PROTOCOLS); if (protocolList != null) { protocols = new HashSet<>(Arrays.asList(protocolList.split("[, ]"))); @@ -47,7 +55,7 @@ public class TimeHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { - if (msg instanceof Position && (protocols == null + if (enabled && msg instanceof Position && (protocols == null || protocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName()))) { Position position = (Position) msg; diff --git a/src/main/java/org/traccar/handler/events/AlertEventHandler.java b/src/main/java/org/traccar/handler/events/AlertEventHandler.java index 05dbc516e..6e7b0b16e 100644 --- a/src/main/java/org/traccar/handler/events/AlertEventHandler.java +++ b/src/main/java/org/traccar/handler/events/AlertEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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,12 +25,15 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class AlertEventHandler extends BaseEventHandler { private final IdentityManager identityManager; private final boolean ignoreDuplicateAlerts; + @Inject public AlertEventHandler(Config config, IdentityManager identityManager) { this.identityManager = identityManager; ignoreDuplicateAlerts = config.getBoolean(Keys.EVENT_IGNORE_DUPLICATE_ALERTS); diff --git a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java index 767cef3f6..bbf749cdc 100644 --- a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@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.helper.UnitsConverter; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; import java.util.Collections; import java.util.Map; @@ -34,6 +35,7 @@ public class BehaviorEventHandler extends BaseEventHandler { private final IdentityManager identityManager; + @Inject public BehaviorEventHandler(Config config, IdentityManager identityManager) { accelerationThreshold = config.getDouble(Keys.EVENT_BEHAVIOR_ACCELERATION_THRESHOLD); brakingThreshold = config.getDouble(Keys.EVENT_BEHAVIOR_BRAKING_THRESHOLD); diff --git a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java index 9b7ff554e..858f84e09 100644 --- a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java +++ b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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,15 @@ import io.netty.channel.ChannelHandler; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class CommandResultEventHandler extends BaseEventHandler { + @Inject + public CommandResultEventHandler() { + } + @Override protected Map analyzePosition(Position position) { Object commandResult = position.getAttributes().get(Position.KEY_RESULT); diff --git a/src/main/java/org/traccar/handler/events/DriverEventHandler.java b/src/main/java/org/traccar/handler/events/DriverEventHandler.java index 6fdf4246b..510ac3465 100644 --- a/src/main/java/org/traccar/handler/events/DriverEventHandler.java +++ b/src/main/java/org/traccar/handler/events/DriverEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,11 +24,14 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class DriverEventHandler extends BaseEventHandler { private final IdentityManager identityManager; + @Inject public DriverEventHandler(IdentityManager identityManager) { this.identityManager = identityManager; } diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java index 343a17311..7849abff9 100644 --- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; import java.util.Collections; import java.util.Map; @@ -31,6 +32,7 @@ public class FuelDropEventHandler extends BaseEventHandler { private final IdentityManager identityManager; + @Inject public FuelDropEventHandler(IdentityManager identityManager) { this.identityManager = identityManager; } diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index dae0c891f..36df7aaf3 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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,8 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { @@ -38,6 +40,7 @@ public class GeofenceEventHandler extends BaseEventHandler { private final CalendarManager calendarManager; private final ConnectionManager connectionManager; + @Inject public GeofenceEventHandler( IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager, ConnectionManager connectionManager) { diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java index 69df9a46b..9887c9db6 100644 --- a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,11 +25,14 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class IgnitionEventHandler extends BaseEventHandler { private final IdentityManager identityManager; + @Inject public IgnitionEventHandler(IdentityManager identityManager) { this.identityManager = identityManager; } diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 0f960ad1f..5b9ce4316 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,12 +26,15 @@ import org.traccar.model.Event; import org.traccar.model.Maintenance; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class MaintenanceEventHandler extends BaseEventHandler { private final IdentityManager identityManager; private final MaintenancesManager maintenancesManager; + @Inject public MaintenanceEventHandler(IdentityManager identityManager, MaintenancesManager maintenancesManager) { this.identityManager = identityManager; this.maintenancesManager = maintenancesManager; diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index db276f32b..23a39d070 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,6 +29,8 @@ import org.traccar.model.Position; import org.traccar.reports.ReportUtils; import org.traccar.reports.model.TripsConfig; +import javax.inject.Inject; + @ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { @@ -36,6 +38,7 @@ public class MotionEventHandler extends BaseEventHandler { private final DeviceManager deviceManager; private final TripsConfig tripsConfig; + @Inject public MotionEventHandler(IdentityManager identityManager, DeviceManager deviceManager, TripsConfig tripsConfig) { this.identityManager = identityManager; this.deviceManager = deviceManager; diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 347ad9005..102003c3c 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,6 +30,8 @@ import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; +import javax.inject.Inject; + @ChannelHandler.Sharable public class OverspeedEventHandler extends BaseEventHandler { @@ -43,6 +45,7 @@ public class OverspeedEventHandler extends BaseEventHandler { private final long minimalDuration; private final boolean preferLowest; + @Inject public OverspeedEventHandler(Config config, DeviceManager deviceManager, GeofenceManager geofenceManager) { this.deviceManager = deviceManager; this.geofenceManager = geofenceManager; diff --git a/src/main/java/org/traccar/reports/model/TripsConfig.java b/src/main/java/org/traccar/reports/model/TripsConfig.java index 0f0c615d3..34c445f8b 100644 --- a/src/main/java/org/traccar/reports/model/TripsConfig.java +++ b/src/main/java/org/traccar/reports/model/TripsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 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,6 @@ package org.traccar.reports.model; public class TripsConfig { - public TripsConfig() { - } - public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { this.minimalTripDistance = minimalTripDistance; @@ -32,74 +29,46 @@ public class TripsConfig { this.speedThreshold = speedThreshold; } - private double minimalTripDistance; + private final double minimalTripDistance; public double getMinimalTripDistance() { return minimalTripDistance; } - public void setMinimalTripDistance(double minimalTripDistance) { - this.minimalTripDistance = minimalTripDistance; - } - - private long minimalTripDuration; + private final long minimalTripDuration; public long getMinimalTripDuration() { return minimalTripDuration; } - public void setMinimalTripDuration(long minimalTripDuration) { - this.minimalTripDuration = minimalTripDuration; - } - - private long minimalParkingDuration; + private final long minimalParkingDuration; public long getMinimalParkingDuration() { return minimalParkingDuration; } - public void setMinimalParkingDuration(long minimalParkingDuration) { - this.minimalParkingDuration = minimalParkingDuration; - } - - private long minimalNoDataDuration; + private final long minimalNoDataDuration; public long getMinimalNoDataDuration() { return minimalNoDataDuration; } - public void setMinimalNoDataDuration(long minimalNoDataDuration) { - this.minimalNoDataDuration = minimalNoDataDuration; - } - - private boolean useIgnition; + private final boolean useIgnition; public boolean getUseIgnition() { return useIgnition; } - public void setUseIgnition(boolean useIgnition) { - this.useIgnition = useIgnition; - } - - private boolean processInvalidPositions; + private final boolean processInvalidPositions; public boolean getProcessInvalidPositions() { return processInvalidPositions; } - public void setProcessInvalidPositions(boolean processInvalidPositions) { - this.processInvalidPositions = processInvalidPositions; - } - - private double speedThreshold; + private final double speedThreshold; public double getSpeedThreshold() { return speedThreshold; } - public void setSpeedThreshold(double speedThreshold) { - this.speedThreshold = speedThreshold; - } - } diff --git a/src/test/java/org/traccar/TestIdentityManager.java b/src/test/java/org/traccar/TestIdentityManager.java index 7d2865e74..68d98db9a 100644 --- a/src/test/java/org/traccar/TestIdentityManager.java +++ b/src/test/java/org/traccar/TestIdentityManager.java @@ -53,9 +53,6 @@ public final class TestIdentityManager implements IdentityManager { @Override public String lookupAttributeString( long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig) { - if (attributeName.equals("filter.skipAttributes")) { - return "alarm,result"; - } return defaultValue; } diff --git a/src/test/java/org/traccar/handler/FilterHandlerTest.java b/src/test/java/org/traccar/handler/FilterHandlerTest.java index ad8d244a6..49bbf70b5 100644 --- a/src/test/java/org/traccar/handler/FilterHandlerTest.java +++ b/src/test/java/org/traccar/handler/FilterHandlerTest.java @@ -5,70 +5,77 @@ import org.junit.Test; import org.traccar.BaseTest; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.DataManager; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; import org.traccar.model.Position; - import java.util.Date; - import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.*; public class FilterHandlerTest extends BaseTest { - private FilterHandler passingHandler = new FilterHandler(new Config()); + private FilterHandler passingHandler; private FilterHandler filteringHandler; @Before - public void before() { - Config config = new Config(); - config.setString(Keys.FILTER_INVALID, String.valueOf(true)); - config.setString(Keys.FILTER_ZERO, String.valueOf(true)); - config.setString(Keys.FILTER_DUPLICATE, String.valueOf(true)); - config.setString(Keys.FILTER_FUTURE, String.valueOf(5 * 60)); - config.setString(Keys.FILTER_APPROXIMATE, String.valueOf(true)); - config.setString(Keys.FILTER_STATIC, String.valueOf(true)); - config.setString(Keys.FILTER_DISTANCE, String.valueOf(10)); - config.setString(Keys.FILTER_MAX_SPEED, String.valueOf(500)); - config.setString(Keys.FILTER_SKIP_LIMIT, String.valueOf(10)); - config.setString(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE, String.valueOf(true)); - filteringHandler = new FilterHandler(config); + public void passingHandler() { + var config = mock(Config.class); + when(config.getBoolean(Keys.FILTER_ENABLE)).thenReturn(true); + var identityManager = mock(IdentityManager.class); + var dataManager = mock(DataManager.class); + passingHandler = new FilterHandler(config, identityManager, dataManager); } - private Position createPosition( - long deviceId, - Date time, - boolean valid, - double latitude, - double longitude, - double altitude, - double speed, - double course) { + @Before + public void filteringHandler() { + var config = mock(Config.class); + when(config.getBoolean(Keys.FILTER_ENABLE)).thenReturn(true); + when(config.getBoolean(Keys.FILTER_INVALID)).thenReturn(true); + when(config.getBoolean(Keys.FILTER_ZERO)).thenReturn(true); + when(config.getBoolean(Keys.FILTER_DUPLICATE)).thenReturn(true); + when(config.getLong(Keys.FILTER_FUTURE)).thenReturn(5 * 60L); + when(config.getBoolean(Keys.FILTER_APPROXIMATE)).thenReturn(true); + when(config.getBoolean(Keys.FILTER_STATIC)).thenReturn(true); + when(config.getInteger(Keys.FILTER_DISTANCE)).thenReturn(10); + when(config.getInteger(Keys.FILTER_MAX_SPEED)).thenReturn(500); + when(config.getLong(Keys.FILTER_SKIP_LIMIT)).thenReturn(10L); + when(config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE)).thenReturn(true); + var identityManager = mock(IdentityManager.class); + when(identityManager.lookupAttributeString(0, "filter.skipAttributes", "", false, true)).thenReturn("alarm,result"); + when(identityManager.getById(0)).thenReturn(mock(Device.class)); + var dataManager = mock(DataManager.class); + filteringHandler = new FilterHandler(config, identityManager, dataManager); + } + private Position createPosition(Date time, boolean valid, double speed) { Position position = new Position(); - position.setDeviceId(deviceId); + position.setDeviceId(0); position.setTime(time); position.setValid(valid); - position.setLatitude(latitude); - position.setLongitude(longitude); - position.setAltitude(altitude); + position.setLatitude(10); + position.setLongitude(10); + position.setAltitude(10); position.setSpeed(speed); - position.setCourse(course); + position.setCourse(10); return position; } @Test public void testFilter() { - Position position = createPosition(0, new Date(), true, 10, 10, 10, 10, 10); + Position position = createPosition(new Date(), true, 10); assertNotNull(filteringHandler.handlePosition(position)); assertNotNull(passingHandler.handlePosition(position)); - position = createPosition(0, new Date(Long.MAX_VALUE), true, 10, 10, 10, 10, 10); + position = createPosition(new Date(Long.MAX_VALUE), true, 10); assertNull(filteringHandler.handlePosition(position)); assertNotNull(passingHandler.handlePosition(position)); - position = createPosition(0, new Date(), false, 10, 10, 10, 10, 10); + position = createPosition(new Date(), false, 10); assertNull(filteringHandler.handlePosition(position)); assertNotNull(passingHandler.handlePosition(position)); @@ -78,7 +85,7 @@ public class FilterHandlerTest extends BaseTest { @Test public void testSkipAttributes() { - Position position = createPosition(0, new Date(), true, 10, 10, 10, 0, 10); + Position position = createPosition(new Date(), true, 0); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); assertNotNull(filteringHandler.handlePosition(position)); diff --git a/src/test/java/org/traccar/handler/MotionHandlerTest.java b/src/test/java/org/traccar/handler/MotionHandlerTest.java index 9e0859664..fdbd48334 100644 --- a/src/test/java/org/traccar/handler/MotionHandlerTest.java +++ b/src/test/java/org/traccar/handler/MotionHandlerTest.java @@ -1,16 +1,21 @@ package org.traccar.handler; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; import org.junit.Test; import org.traccar.model.Position; +import org.traccar.reports.model.TripsConfig; public class MotionHandlerTest { @Test public void testCalculateMotion() { - MotionHandler motionHandler = new MotionHandler(0.01); + TripsConfig tripsConfig = mock(TripsConfig.class); + when(tripsConfig.getSpeedThreshold()).thenReturn(0.01); + + MotionHandler motionHandler = new MotionHandler(tripsConfig); Position position = motionHandler.handlePosition(new Position()); -- cgit v1.2.3 From 014cf82a9e63a36e944e293932f9edf27e452919 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 14:04:24 -0700 Subject: No context dependency for decoder --- src/main/java/org/traccar/BaseProtocolDecoder.java | 42 ++++++++++++++++++---- src/main/java/org/traccar/Main.java | 2 +- src/main/java/org/traccar/model/BaseModel.java | 6 ++-- src/main/java/org/traccar/model/CellTower.java | 14 ++++---- .../traccar/protocol/AplicomProtocolDecoder.java | 3 +- .../traccar/protocol/AtrackProtocolDecoder.java | 16 +++++---- .../traccar/protocol/Avl301ProtocolDecoder.java | 2 +- .../traccar/protocol/CastelProtocolDecoder.java | 4 +-- .../org/traccar/protocol/EsealProtocolDecoder.java | 9 +++-- .../org/traccar/protocol/GenxProtocolDecoder.java | 7 ++-- .../traccar/protocol/Gl200TextProtocolDecoder.java | 11 +++--- .../traccar/protocol/GlobalSatProtocolDecoder.java | 8 +++-- .../traccar/protocol/Gps103ProtocolDecoder.java | 3 +- .../org/traccar/protocol/H02ProtocolDecoder.java | 6 ++-- .../traccar/protocol/HuabaoProtocolDecoder.java | 3 +- .../org/traccar/protocol/Jt600ProtocolDecoder.java | 7 ++-- .../java/org/traccar/protocol/OrbcommProtocol.java | 3 +- .../traccar/protocol/OrbcommProtocolPoller.java | 12 +++---- .../traccar/protocol/SkypatrolProtocolDecoder.java | 9 +++-- .../traccar/protocol/StarLinkProtocolDecoder.java | 9 +++-- .../traccar/protocol/TechTltProtocolDecoder.java | 2 +- .../traccar/protocol/TeltonikaProtocolDecoder.java | 11 ++++-- .../traccar/protocol/ThinkRaceProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tk103ProtocolDecoder.java | 9 +++-- .../org/traccar/protocol/TotemProtocolDecoder.java | 6 ++-- .../org/traccar/protocol/TzoneProtocolDecoder.java | 5 ++- .../org/traccar/protocol/XirgoProtocolDecoder.java | 7 ++-- .../traccar/protocol/Xt2400ProtocolDecoder.java | 6 ++-- src/test/java/org/traccar/BaseTest.java | 30 ++++++++++++++++ .../org/traccar/protocol/AdmFrameDecoderTest.java | 2 +- .../traccar/protocol/AdmProtocolDecoderTest.java | 2 +- .../traccar/protocol/AisProtocolDecoderTest.java | 2 +- .../protocol/AlematicsProtocolDecoderTest.java | 2 +- .../protocol/AnytrekProtocolDecoderTest.java | 2 +- .../traccar/protocol/ApelProtocolDecoderTest.java | 2 +- .../traccar/protocol/AplicomFrameDecoderTest.java | 2 +- .../protocol/AplicomProtocolDecoderTest.java | 2 +- .../protocol/AppelloProtocolDecoderTest.java | 2 +- .../protocol/AquilaProtocolDecoderTest.java | 2 +- .../protocol/Ardi01ProtocolDecoderTest.java | 2 +- .../protocol/ArknavProtocolDecoderTest.java | 2 +- .../protocol/ArknavX8ProtocolDecoderTest.java | 2 +- .../protocol/ArmoliProtocolDecoderTest.java | 2 +- .../protocol/ArnaviBinaryProtocolDecoderTest.java | 8 ++--- .../traccar/protocol/ArnaviFrameDecoderTest.java | 2 +- .../protocol/ArnaviTextProtocolDecoderTest.java | 2 +- .../traccar/protocol/AstraProtocolDecoderTest.java | 2 +- .../traccar/protocol/At2000FrameDecoderTest.java | 2 +- .../traccar/protocol/AtrackFrameDecoderTest.java | 2 +- .../protocol/AtrackProtocolDecoderTest.java | 4 +-- .../traccar/protocol/AuroProtocolDecoderTest.java | 2 +- .../protocol/AustinNbProtocolDecoderTest.java | 2 +- .../protocol/AutoFonProtocolDecoderTest.java | 2 +- .../protocol/AutoGradeProtocolDecoderTest.java | 2 +- .../protocol/AutoTrackProtocolDecoderTest.java | 2 +- .../traccar/protocol/AvemaProtocolDecoderTest.java | 2 +- .../protocol/Avl301ProtocolDecoderTest.java | 2 +- .../traccar/protocol/B2316ProtocolDecoderTest.java | 2 +- .../traccar/protocol/BceProtocolDecoderTest.java | 2 +- .../protocol/BlackKiteProtocolDecoderTest.java | 2 +- .../traccar/protocol/BlueProtocolDecoderTest.java | 2 +- .../traccar/protocol/BoxProtocolDecoderTest.java | 2 +- .../protocol/C2stekProtocolDecoderTest.java | 2 +- .../protocol/CalAmpProtocolDecoderTest.java | 2 +- .../protocol/CarTrackProtocolDecoderTest.java | 2 +- .../protocol/CarscopProtocolDecoderTest.java | 2 +- .../protocol/CastelProtocolDecoderTest.java | 2 +- .../protocol/CautelaProtocolDecoderTest.java | 2 +- .../protocol/CellocatorFrameDecoderTest.java | 2 +- .../protocol/CellocatorProtocolDecoderTest.java | 2 +- .../protocol/CguardProtocolDecoderTest.java | 2 +- .../protocol/CityeasyProtocolDecoderTest.java | 2 +- .../protocol/ContinentalProtocolDecoderTest.java | 2 +- .../protocol/CradlepointProtocolDecoderTest.java | 2 +- .../traccar/protocol/DingtekFrameDecoderTest.java | 2 +- .../protocol/DingtekProtocolDecoderTest.java | 2 +- .../traccar/protocol/DishaProtocolDecoderTest.java | 2 +- .../protocol/DmtHttpProtocolDecoderTest.java | 2 +- .../traccar/protocol/DmtProtocolDecoderTest.java | 2 +- .../protocol/DolphinProtocolDecoderTest.java | 2 +- .../traccar/protocol/Dsf22FrameDecoderTest.java | 2 +- .../traccar/protocol/Dsf22ProtocolDecoderTest.java | 2 +- .../traccar/protocol/DualcamFrameDecoderTest.java | 2 +- .../protocol/DualcamProtocolDecoderTest.java | 2 +- .../traccar/protocol/DwayProtocolDecoderTest.java | 2 +- .../protocol/EasyTrackProtocolDecoderTest.java | 2 +- .../protocol/EelinkProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/EgtsFrameDecoderTest.java | 2 +- .../traccar/protocol/EgtsProtocolDecoderTest.java | 4 +-- .../protocol/EnforaProtocolDecoderTest.java | 2 +- .../traccar/protocol/EnnfuProtocolDecoderTest.java | 2 +- .../protocol/EnvotechProtocolDecoderTest.java | 2 +- .../traccar/protocol/EsealProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/EskyFrameDecoderTest.java | 2 +- .../traccar/protocol/EskyProtocolDecoderTest.java | 2 +- .../protocol/ExtremTracProtocolDecoderTest.java | 2 +- .../protocol/FifotrackFrameDecoderTest.java | 2 +- .../protocol/FifotrackProtocolDecoderTest.java | 2 +- .../protocol/FlespiProtocolDecoderTest.java | 2 +- .../protocol/FlexApiProtocolDecoderTest.java | 2 +- .../protocol/FlexCommProtocolDecoderTest.java | 2 +- .../FlexibleReportProtocolDecoderTest.java | 2 +- .../protocol/FlextrackProtocolDecoderTest.java | 2 +- .../traccar/protocol/FoxProtocolDecoderTest.java | 2 +- .../protocol/FreedomProtocolDecoderTest.java | 2 +- .../protocol/FreematicsProtocolDecoderTest.java | 2 +- .../protocol/FutureWayFrameDecoderTest.java | 2 +- .../protocol/FutureWayProtocolDecoderTest.java | 2 +- .../traccar/protocol/GalileoFrameDecoderTest.java | 2 +- .../protocol/GalileoProtocolDecoderTest.java | 2 +- .../traccar/protocol/GatorProtocolDecoderTest.java | 2 +- .../traccar/protocol/GenxProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gl100ProtocolDecoderTest.java | 2 +- .../protocol/Gl200BinaryProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gl200FrameDecoderTest.java | 2 +- .../protocol/Gl200TextProtocolDecoderTest.java | 2 +- .../protocol/GlobalSatProtocolDecoderTest.java | 2 +- .../protocol/GlobalstarProtocolDecoderTest.java | 2 +- .../traccar/protocol/GnxProtocolDecoderTest.java | 2 +- .../protocol/GoSafeProtocolDecoderTest.java | 2 +- .../traccar/protocol/GotopProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gps056FrameDecoderTest.java | 2 +- .../protocol/Gps056ProtocolDecoderTest.java | 2 +- .../protocol/Gps103ProtocolDecoderTest.java | 2 +- .../protocol/GpsGateProtocolDecoderTest.java | 2 +- .../protocol/GpsMarkerProtocolDecoderTest.java | 2 +- .../protocol/GpsmtaProtocolDecoderTest.java | 2 +- .../traccar/protocol/GranitFrameDecoderTest.java | 2 +- .../protocol/GranitProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gs100ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gt02ProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/Gt06FrameDecoderTest.java | 2 +- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Gt30ProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/H02FrameDecoderTest.java | 6 ++-- .../traccar/protocol/H02ProtocolDecoderTest.java | 4 +-- .../protocol/HaicomProtocolDecoderTest.java | 2 +- .../protocol/HomtecsProtocolDecoderTest.java | 2 +- .../traccar/protocol/HoopoProtocolDecoderTest.java | 2 +- .../traccar/protocol/HuaShengFrameDecoderTest.java | 2 +- .../protocol/HuaShengProtocolDecoderTest.java | 2 +- .../traccar/protocol/HuabaoFrameDecoderTest.java | 2 +- .../protocol/HuabaoProtocolDecoderTest.java | 2 +- .../protocol/HunterProProtocolDecoderTest.java | 2 +- .../traccar/protocol/IdplProtocolDecoderTest.java | 2 +- .../protocol/IntellitracProtocolDecoderTest.java | 2 +- .../traccar/protocol/IotmProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/ItsFrameDecoderTest.java | 2 +- .../traccar/protocol/ItsProtocolDecoderTest.java | 2 +- .../protocol/Ivt401ProtocolDecoderTest.java | 2 +- .../traccar/protocol/JidoProtocolDecoderTest.java | 2 +- .../protocol/JpKorjarProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/JsonFrameDecoderTest.java | 2 +- .../traccar/protocol/Jt600FrameDecoderTest.java | 2 +- .../traccar/protocol/Jt600ProtocolDecoderTest.java | 2 +- .../traccar/protocol/KenjiProtocolDecoderTest.java | 2 +- .../traccar/protocol/KhdProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/L100FrameDecoderTest.java | 2 +- .../traccar/protocol/L100ProtocolDecoderTest.java | 2 +- .../traccar/protocol/LacakProtocolDecoderTest.java | 2 +- .../protocol/LaipacProtocolDecoderTest.java | 2 +- .../protocol/LeafSpyProtocolDecoderTest.java | 2 +- .../traccar/protocol/M2cProtocolDecoderTest.java | 2 +- .../traccar/protocol/M2mProtocolDecoderTest.java | 2 +- .../protocol/MaestroProtocolDecoderTest.java | 2 +- .../protocol/ManPowerProtocolDecoderTest.java | 2 +- .../protocol/Mavlink2ProtocolDecoderTest.java | 2 +- .../traccar/protocol/MegastekFrameDecoderTest.java | 2 +- .../protocol/MegastekProtocolDecoderTest.java | 2 +- .../traccar/protocol/MeiligaoFrameDecoderTest.java | 2 +- .../protocol/MeiligaoProtocolDecoderTest.java | 2 +- .../traccar/protocol/MeitrackFrameDecoderTest.java | 2 +- .../protocol/MeitrackProtocolDecoderTest.java | 2 +- .../protocol/MictrackProtocolDecoderTest.java | 4 +-- .../protocol/MilesmateProtocolDecoderTest.java | 2 +- .../protocol/MiniFinderProtocolDecoderTest.java | 2 +- .../protocol/Minifinder2ProtocolDecoderTest.java | 2 +- .../protocol/MobilogixProtocolDecoderTest.java | 2 +- .../protocol/MoovboxProtocolDecoderTest.java | 2 +- .../traccar/protocol/MotorProtocolDecoderTest.java | 2 +- .../traccar/protocol/MtxProtocolDecoderTest.java | 2 +- .../traccar/protocol/MxtProtocolDecoderTest.java | 2 +- .../protocol/NavigilProtocolDecoderTest.java | 2 +- .../traccar/protocol/NavisProtocolDecoderTest.java | 6 ++-- .../traccar/protocol/NavisetFrameDecoderTest.java | 2 +- .../protocol/NavisetProtocolDecoderTest.java | 2 +- .../protocol/NavtelecomFrameDecoderTest.java | 4 +-- .../protocol/NavtelecomProtocolDecoderTest.java | 2 +- .../traccar/protocol/NeosProtocolDecoderTest.java | 2 +- .../traccar/protocol/NetProtocolDecoderTest.java | 2 +- .../traccar/protocol/NiotProtocolDecoderTest.java | 2 +- .../traccar/protocol/NoranProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/NvsFrameDecoderTest.java | 2 +- .../traccar/protocol/NvsProtocolDecoderTest.java | 2 +- .../protocol/NyitechProtocolDecoderTest.java | 2 +- .../protocol/ObdDongleProtocolDecoderTest.java | 2 +- .../traccar/protocol/OigoProtocolDecoderTest.java | 2 +- .../traccar/protocol/OkoProtocolDecoderTest.java | 2 +- .../traccar/protocol/OmnicommFrameDecoderTest.java | 2 +- .../protocol/OmnicommProtocolDecoderTest.java | 2 +- .../protocol/OpenGtsProtocolDecoderTest.java | 2 +- .../protocol/OrbcommProtocolDecoderTest.java | 2 +- .../traccar/protocol/OrionProtocolDecoderTest.java | 2 +- .../protocol/OsmAndProtocolDecoderTest.java | 2 +- .../protocol/OutsafeProtocolDecoderTest.java | 2 +- .../protocol/OwnTracksProtocolDecoderTest.java | 2 +- .../protocol/PacificTrackProtocolDecoderTest.java | 2 +- .../protocol/PathAwayProtocolDecoderTest.java | 2 +- .../protocol/PiligrimProtocolDecoderTest.java | 2 +- .../protocol/PluginProtocolDecoderTest.java | 2 +- .../traccar/protocol/PolteProtocolDecoderTest.java | 2 +- .../protocol/PortmanProtocolDecoderTest.java | 2 +- .../protocol/PretraceProtocolDecoderTest.java | 2 +- .../protocol/PricolProtocolDecoderTest.java | 2 +- .../protocol/ProgressProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/PstFrameDecoderTest.java | 2 +- .../traccar/protocol/PstProtocolDecoderTest.java | 2 +- .../traccar/protocol/Pt215ProtocolDecoderTest.java | 2 +- .../protocol/Pt3000ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Pt502FrameDecoderTest.java | 2 +- .../traccar/protocol/Pt502ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Pt60ProtocolDecoderTest.java | 2 +- .../traccar/protocol/R12wProtocolDecoderTest.java | 2 +- .../protocol/RaceDynamicsProtocolDecoderTest.java | 2 +- .../traccar/protocol/RadarProtocolDecoderTest.java | 2 +- .../protocol/RaveonProtocolDecoderTest.java | 2 +- .../protocol/RecodaProtocolDecoderTest.java | 2 +- .../protocol/RetranslatorProtocolDecoderTest.java | 2 +- .../traccar/protocol/RitiProtocolDecoderTest.java | 2 +- .../protocol/RoboTrackFrameDecoderTest.java | 2 +- .../protocol/RoboTrackProtocolDecoderTest.java | 2 +- .../traccar/protocol/RstProtocolDecoderTest.java | 2 +- .../protocol/RuptelaProtocolDecoderTest.java | 2 +- .../traccar/protocol/S168ProtocolDecoderTest.java | 2 +- .../traccar/protocol/SabertekFrameDecoderTest.java | 2 +- .../protocol/SabertekProtocolDecoderTest.java | 2 +- .../traccar/protocol/SanavProtocolDecoderTest.java | 2 +- .../traccar/protocol/SanulProtocolDecoderTest.java | 2 +- .../protocol/SatsolProtocolDecoderTest.java | 2 +- .../protocol/SigfoxProtocolDecoderTest.java | 2 +- .../traccar/protocol/SiwiProtocolDecoderTest.java | 2 +- .../protocol/SkypatrolProtocolDecoderTest.java | 2 +- .../protocol/SmartSoleProtocolDecoderTest.java | 2 +- .../protocol/SmokeyProtocolDecoderTest.java | 2 +- .../protocol/SolarPoweredProtocolDecoderTest.java | 2 +- .../traccar/protocol/SpotProtocolDecoderTest.java | 2 +- .../protocol/StarLinkProtocolDecoderTest.java | 2 +- .../protocol/StarcomProtocolDecoderTest.java | 2 +- .../protocol/StartekProtocolDecoderTest.java | 2 +- .../traccar/protocol/StbProtocolDecoderTest.java | 2 +- .../protocol/Stl060ProtocolDecoderTest.java | 2 +- .../traccar/protocol/SuntechFrameDecoderTest.java | 2 +- .../protocol/SuntechProtocolDecoderTest.java | 12 +++---- .../protocol/SupermateProtocolDecoderTest.java | 2 +- .../traccar/protocol/SviasProtocolDecoderTest.java | 2 +- .../protocol/SwiftechProtocolDecoderTest.java | 2 +- .../traccar/protocol/T55ProtocolDecoderTest.java | 4 +-- .../org/traccar/protocol/T57FrameDecoderTest.java | 2 +- .../traccar/protocol/T57ProtocolDecoderTest.java | 2 +- .../traccar/protocol/T800xProtocolDecoderTest.java | 2 +- .../traccar/protocol/TaipProtocolDecoderTest.java | 2 +- .../protocol/TechTltProtocolDecoderTest.java | 2 +- .../protocol/TechtoCruzFrameDecoderTest.java | 2 +- .../protocol/TechtoCruzProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/TekFrameDecoderTest.java | 2 +- .../traccar/protocol/TekProtocolDecoderTest.java | 2 +- .../protocol/TelemaxProtocolDecoderTest.java | 2 +- .../traccar/protocol/TelicFrameDecoderTest.java | 2 +- .../traccar/protocol/TelicProtocolDecoderTest.java | 2 +- .../protocol/TeltonikaFrameDecoderTest.java | 2 +- .../protocol/TeltonikaProtocolDecoderTest.java | 6 ++-- .../protocol/TeraTrackProtocolDecoderTest.java | 2 +- .../protocol/ThinkPowerProtocolDecoderTest.java | 2 +- .../protocol/ThinkRaceProtocolDecoderTest.java | 2 +- .../traccar/protocol/Tk102ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Tk103FrameDecoderTest.java | 2 +- .../traccar/protocol/Tk103ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Tlt2hProtocolDecoderTest.java | 2 +- .../traccar/protocol/TlvProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/TmgFrameDecoderTest.java | 2 +- .../traccar/protocol/TmgProtocolDecoderTest.java | 2 +- .../protocol/TopflytechProtocolDecoderTest.java | 2 +- .../traccar/protocol/TopinProtocolDecoderTest.java | 2 +- .../traccar/protocol/TotemFrameDecoderTest.java | 2 +- .../traccar/protocol/TotemProtocolDecoderTest.java | 2 +- .../traccar/protocol/Tr20ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Tr900ProtocolDecoderTest.java | 2 +- .../protocol/TrackboxProtocolDecoderTest.java | 2 +- .../protocol/TrakMateProtocolDecoderTest.java | 2 +- .../traccar/protocol/TramigoFrameDecoderTest.java | 2 +- .../protocol/TramigoProtocolDecoderTest.java | 2 +- .../traccar/protocol/TrvProtocolDecoderTest.java | 2 +- .../protocol/Tt8850ProtocolDecoderTest.java | 2 +- .../traccar/protocol/TytanProtocolDecoderTest.java | 2 +- .../traccar/protocol/TzoneProtocolDecoderTest.java | 2 +- .../traccar/protocol/UlbotechFrameDecoderTest.java | 2 +- .../protocol/UlbotechProtocolDecoderTest.java | 2 +- .../traccar/protocol/UproProtocolDecoderTest.java | 2 +- .../traccar/protocol/UuxProtocolDecoderTest.java | 2 +- .../traccar/protocol/V680ProtocolDecoderTest.java | 2 +- .../protocol/VisiontekProtocolDecoderTest.java | 2 +- .../traccar/protocol/VnetProtocolDecoderTest.java | 2 +- .../traccar/protocol/Vt200FrameDecoderTest.java | 2 +- .../traccar/protocol/Vt200ProtocolDecoderTest.java | 2 +- .../traccar/protocol/VtfmsFrameDecoderTest.java | 2 +- .../traccar/protocol/VtfmsProtocolDecoderTest.java | 2 +- .../traccar/protocol/WatchFrameDecoderTest.java | 2 +- .../traccar/protocol/WatchProtocolDecoderTest.java | 4 +-- .../protocol/WialonProtocolDecoderTest.java | 2 +- .../org/traccar/protocol/WliFrameDecoderTest.java | 2 +- .../traccar/protocol/WliProtocolDecoderTest.java | 2 +- .../traccar/protocol/WondexFrameDecoderTest.java | 2 +- .../protocol/WondexProtocolDecoderTest.java | 2 +- .../protocol/WristbandProtocolDecoderTest.java | 2 +- .../traccar/protocol/Xexun2FrameDecoderTest.java | 2 +- .../protocol/Xexun2ProtocolDecoderTest.java | 2 +- .../traccar/protocol/XexunFrameDecoderTest.java | 2 +- .../traccar/protocol/XexunProtocolDecoderTest.java | 11 ++++-- .../traccar/protocol/XirgoProtocolDecoderTest.java | 6 ++-- .../traccar/protocol/Xrb28ProtocolDecoderTest.java | 2 +- .../traccar/protocol/Xt013ProtocolDecoderTest.java | 2 +- .../protocol/Xt2400ProtocolDecoderTest.java | 2 +- .../traccar/protocol/YwtProtocolDecoderTest.java | 2 +- 323 files changed, 495 insertions(+), 402 deletions(-) diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 505e7926f..0f62c87df 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,17 +50,47 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private static final String PROTOCOL_UNKNOWN = "unknown"; - private final Config config = Context.getConfig(); - private final IdentityManager identityManager = Context.getIdentityManager(); - private final ConnectionManager connectionManager = Context.getConnectionManager(); - private final StatisticsManager statisticsManager; private final Protocol protocol; + private Config config; + private IdentityManager identityManager; + private ConnectionManager connectionManager; + private StatisticsManager statisticsManager; private MediaManager mediaManager; public BaseProtocolDecoder(Protocol protocol) { this.protocol = protocol; - statisticsManager = Main.getInjector() != null ? Main.getInjector().getInstance(StatisticsManager.class) : null; + } + + /** + * Method called when config is initialized. + */ + protected void init() { + } + + public Config getConfig() { + return config; + } + + @Inject + public void setConfig(Config config) { + this.config = config; + init(); + } + + @Inject + public void setIdentityManager(IdentityManager identityManager) { + this.identityManager = identityManager; + } + + @Inject + public void setConnectionManager(ConnectionManager connectionManager) { + this.connectionManager = connectionManager; + } + + @Inject + public void setStatisticsManager(StatisticsManager statisticsManager) { + this.statisticsManager = statisticsManager; } @Inject diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 2eaf394af..016365837 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -110,8 +110,8 @@ public final class Main { public static void run(String configFile) { try { - Context.init(configFile); injector = Guice.createInjector(new MainModule()); + Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); LOGGER.info("Starting server..."); diff --git a/src/main/java/org/traccar/model/BaseModel.java b/src/main/java/org/traccar/model/BaseModel.java index 8bdb916e8..acde0f83d 100644 --- a/src/main/java/org/traccar/model/BaseModel.java +++ b/src/main/java/org/traccar/model/BaseModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,11 +20,11 @@ public class BaseModel { private long id; - public final long getId() { + public long getId() { return id; } - public final void setId(long id) { + public void setId(long id) { this.id = id; } diff --git a/src/main/java/org/traccar/model/CellTower.java b/src/main/java/org/traccar/model/CellTower.java index 254487471..af33b1f5c 100644 --- a/src/main/java/org/traccar/model/CellTower.java +++ b/src/main/java/org/traccar/model/CellTower.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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,7 +16,7 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonInclude; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; @JsonInclude(JsonInclude.Include.NON_NULL) @@ -37,14 +37,12 @@ public class CellTower { return cellTower; } - public static CellTower fromLacCid(int lac, long cid) { - return from( - Context.getConfig().getInteger(Keys.GEOLOCATION_MCC), - Context.getConfig().getInteger(Keys.GEOLOCATION_MCC), lac, cid); + public static CellTower fromLacCid(Config config, int lac, long cid) { + return from(config.getInteger(Keys.GEOLOCATION_MCC), config.getInteger(Keys.GEOLOCATION_MCC), lac, cid); } - public static CellTower fromCidLac(long cid, int lac) { - return fromLacCid(lac, cid); + public static CellTower fromCidLac(Config config, long cid, int lac) { + return fromLacCid(config, lac, cid); } private String radioType; diff --git a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java index f11312428..692a2058a 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java @@ -21,7 +21,6 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -303,7 +302,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { decodeEventData(position, buf, event); } - if (Context.getConfig().getBoolean(Keys.PROTOCOL_CAN.withPrefix(getProtocolName())) + if (getConfig().getBoolean(Keys.PROTOCOL_CAN.withPrefix(getProtocolName())) && buf.isReadable() && (selector & 0x1000) != 0 && event == EVENT_DATA) { decodeCanData(buf, position); } diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 247a1b696..9a5d537ef 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; 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; @@ -54,7 +53,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { private static final int MIN_DATA_LENGTH = 40; private boolean longDate; - private final boolean decimalFuel; + private boolean decimalFuel; private boolean custom; private String form; @@ -64,17 +63,20 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { public AtrackProtocolDecoder(Protocol protocol) { super(protocol); + } - longDate = Context.getConfig().getBoolean(Keys.PROTOCOL_LONG_DATE.withPrefix(getProtocolName())); - decimalFuel = Context.getConfig().getBoolean(Keys.PROTOCOL_DECIMAL_FUEL.withPrefix(getProtocolName())); + @Override + protected void init() { + longDate = getConfig().getBoolean(Keys.PROTOCOL_LONG_DATE.withPrefix(getProtocolName())); + decimalFuel = getConfig().getBoolean(Keys.PROTOCOL_DECIMAL_FUEL.withPrefix(getProtocolName())); - custom = Context.getConfig().getBoolean(Keys.PROTOCOL_CUSTOM.withPrefix(getProtocolName())); - form = Context.getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); + custom = getConfig().getBoolean(Keys.PROTOCOL_CUSTOM.withPrefix(getProtocolName())); + form = getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); if (form != null) { custom = true; } - String alarmMapString = Context.getConfig().getString(Keys.PROTOCOL_ALARM_MAP.withPrefix(getProtocolName())); + String alarmMapString = getConfig().getString(Keys.PROTOCOL_ALARM_MAP.withPrefix(getProtocolName())); if (alarmMapString != null) { for (String pair : alarmMapString.split(",")) { if (!pair.isEmpty()) { diff --git a/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java index f6b7db2d6..9f6ded26a 100644 --- a/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java @@ -125,7 +125,7 @@ public class Avl301ProtocolDecoder extends BaseProtocolDecoder { } position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedMedium()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShort(), buf.readUnsignedMedium()))); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); int flags = buf.readUnsignedByte(); diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index 23401b5ee..85ac29336 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -443,7 +443,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { decodeStat(position, buf); position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); return position; @@ -499,7 +499,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // additional flags position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShortLE(), buf.readUnsignedShortLE()))); positions.add(position); } diff --git a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java index 0a12f781d..27fcf1394 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java @@ -17,7 +17,6 @@ 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; @@ -32,11 +31,15 @@ import java.util.regex.Pattern; public class EsealProtocolDecoder extends BaseProtocolDecoder { - private final String config; + private String config; public EsealProtocolDecoder(Protocol protocol) { super(protocol); - config = Context.getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + config = getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); } private static final Pattern PATTERN = new PatternBuilder() diff --git a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java index 2ae9de7a0..b787b7467 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; @@ -32,7 +31,11 @@ public class GenxProtocolDecoder extends BaseProtocolDecoder { public GenxProtocolDecoder(Protocol protocol) { super(protocol); - setReportColumns(Context.getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4")); + } + + @Override + protected void init() { + setReportColumns(getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4")); } public void setReportColumns(String format) { diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 280986165..72d3ef592 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -16,7 +16,6 @@ package org.traccar.protocol; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -46,11 +45,15 @@ import java.util.regex.Pattern; public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { - private final boolean ignoreFixTime; + private boolean ignoreFixTime; public Gl200TextProtocolDecoder(Protocol protocol) { super(protocol); - ignoreFixTime = Context.getConfig().getBoolean(Keys.PROTOCOL_IGNORE_FIX_TIME.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + ignoreFixTime = getConfig().getBoolean(Keys.PROTOCOL_IGNORE_FIX_TIME.withPrefix(getProtocolName())); } private static final Pattern PATTERN_ACK = new PatternBuilder() @@ -1333,7 +1336,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } } - if (channel != null && Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + if (channel != null && getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { String checksum; if (sentence.endsWith("$")) { checksum = sentence.substring(sentence.length() - 1 - 4, sentence.length() - 1); diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java index b48df4047..d5c834284 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java @@ -17,7 +17,6 @@ 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; @@ -40,9 +39,12 @@ public class GlobalSatProtocolDecoder extends BaseProtocolDecoder { public GlobalSatProtocolDecoder(Protocol protocol) { super(protocol); + } - format0 = Context.getConfig().getString(getProtocolName() + ".format0", "TSPRXAB27GHKLMnaicz*U!"); - format1 = Context.getConfig().getString(getProtocolName() + ".format1", "SARY*U!"); + @Override + protected void init() { + format0 = getConfig().getString(getProtocolName() + ".format0", "TSPRXAB27GHKLMnaicz*U!"); + format1 = getConfig().getString(getProtocolName() + ".format1", "SARY*U!"); } public void setFormat0(String format) { diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index d5aa45b9c..510f5eca2 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -221,7 +221,8 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.setNetwork(new Network(CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); + position.setNetwork(new Network(CellTower.fromLacCid( + getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); } else { diff --git a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java index 10a272bff..dcfb36fd1 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; 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; @@ -334,7 +333,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext() && parser.next().equals("V1")) { sendResponse(channel, remoteAddress, id, "V1"); - } else if (Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + } else if (getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { sendResponse(channel, remoteAddress, id, "R12"); } @@ -392,7 +391,8 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.setAltitude(parser.nextInt(0)); - position.setNetwork(new Network(CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); + position.setNetwork(new Network(CellTower.fromLacCid( + getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); } if (parser.hasNext()) { diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 9f54c8486..84120028a 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -585,7 +585,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CHARGE, true); } - position.setNetwork(new Network(CellTower.fromCidLac(buf.readUnsignedInt(), buf.readUnsignedShort()))); + position.setNetwork(new Network(CellTower.fromCidLac( + getConfig(), buf.readUnsignedInt(), buf.readUnsignedShort()))); int product = buf.readUnsignedByte(); int status = buf.readUnsignedShort(); diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index b4b70091b..2c1b5dcec 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -177,7 +177,8 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, battery); } - CellTower cellTower = CellTower.fromCidLac(buf.readUnsignedShort(), buf.readUnsignedShort()); + CellTower cellTower = CellTower.fromCidLac( + getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()); cellTower.setSignalStrength((int) buf.readUnsignedByte()); position.setNetwork(new Network(cellTower)); @@ -201,7 +202,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { int rssi = buf.readUnsignedByte(); if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromCidLac(cid, lac); + CellTower cellTower = CellTower.fromCidLac(getConfig(), cid, lac); cellTower.setSignalStrength(rssi); position.setNetwork(new Network(cellTower)); } else { @@ -356,7 +357,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); position.set(Position.KEY_STATUS, parser.nextBinInt(0)); - CellTower cellTower = CellTower.fromCidLac(parser.nextInt(0), parser.nextInt(0)); + CellTower cellTower = CellTower.fromCidLac(getConfig(), parser.nextInt(0), parser.nextInt(0)); cellTower.setSignalStrength(parser.nextInt(0)); position.setNetwork(new Network(cellTower)); diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocol.java b/src/main/java/org/traccar/protocol/OrbcommProtocol.java index bdfce3b1e..2f9f56641 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocol.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestEncoder; import io.netty.handler.codec.http.HttpResponseDecoder; import org.traccar.BaseProtocol; +import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerClient; @@ -32,7 +33,7 @@ public class OrbcommProtocol extends BaseProtocol { pipeline.addLast(new HttpResponseDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); pipeline.addLast(new OrbcommProtocolDecoder(OrbcommProtocol.this)); - pipeline.addLast(new OrbcommProtocolPoller(OrbcommProtocol.this)); + pipeline.addLast(new OrbcommProtocolPoller(OrbcommProtocol.this, Context.getConfig())); } }); } diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java index 6a2d7a92d..0f57bfb49 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolPoller.java @@ -24,8 +24,8 @@ import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.QueryStringEncoder; import org.traccar.BaseProtocolPoller; -import org.traccar.Context; import org.traccar.Protocol; +import org.traccar.config.Config; import org.traccar.config.Keys; import java.net.SocketAddress; @@ -46,11 +46,11 @@ public class OrbcommProtocolPoller extends BaseProtocolPoller { this.startTime = startTime; } - public OrbcommProtocolPoller(Protocol protocol) { - super(Context.getConfig().getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol.getName()))); - accessId = Context.getConfig().getString(Keys.ORBCOMM_ACCESS_ID); - password = Context.getConfig().getString(Keys.ORBCOMM_PASSWORD); - host = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol.getName())); + public OrbcommProtocolPoller(Protocol protocol, Config config) { + super(config.getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol.getName()))); + accessId = config.getString(Keys.ORBCOMM_ACCESS_ID); + password = config.getString(Keys.ORBCOMM_PASSWORD); + host = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol.getName())); } @Override diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java b/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java index 8aae310bb..818acd805 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -35,11 +34,15 @@ public class SkypatrolProtocolDecoder extends BaseProtocolDecoder { private static final Logger LOGGER = LoggerFactory.getLogger(SkypatrolProtocolDecoder.class); - private final long defaultMask; + private long defaultMask; public SkypatrolProtocolDecoder(Protocol protocol) { super(protocol); - defaultMask = Context.getConfig().getInteger(Keys.PROTOCOL_MASK.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + defaultMask = getConfig().getInteger(Keys.PROTOCOL_MASK.withPrefix(getProtocolName())); } private static double convertCoordinate(long coordinate) { diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index 7a6b6f4fe..5e631017e 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -55,12 +55,15 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { public StarLinkProtocolDecoder(Protocol protocol) { super(protocol); + } - setFormat(Context.getConfig().getString( + @Override + protected void init() { + setFormat(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")); + setDateFormat(getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss")); } public String[] getFormat(long deviceId) { @@ -313,7 +316,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } if (lac != null && cid != null) { - position.setNetwork(new Network(CellTower.fromLacCid(lac, cid))); + position.setNetwork(new Network(CellTower.fromLacCid(getConfig(), lac, cid))); } if (event == 20) { diff --git a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java index 17f5c80fa..b6091136a 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java @@ -110,7 +110,7 @@ public class TechTltProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, parser.nextInt()); - position.setNetwork(new Network(CellTower.fromLacCid(parser.nextInt(), parser.nextInt()))); + position.setNetwork(new Network(CellTower.fromLacCid(getConfig(), parser.nextInt(), parser.nextInt()))); return position; } diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 61a61b900..407488527 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -55,7 +55,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { public TeltonikaProtocolDecoder(Protocol protocol, boolean connectionless) { super(protocol); this.connectionless = connectionless; - this.extended = Context.getConfig().getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + this.extended = getConfig().getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getProtocolName())); } private void parseIdentification(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { @@ -360,7 +364,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { long cid = position.getLong(Position.PREFIX_IO + 205); int lac = position.getInteger(Position.PREFIX_IO + 206); if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromLacCid(lac, cid); + CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); long operator = position.getInteger(Position.KEY_OPERATOR); if (operator >= 1000) { cellTower.setOperator(operator); @@ -422,7 +426,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(locationMask, 5)) { - CellTower cellTower = CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()); + CellTower cellTower = CellTower.fromLacCid( + getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()); if (BitUtil.check(locationMask, 6)) { cellTower.setSignalStrength((int) buf.readUnsignedByte()); diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java index 0928b25e0..82033598d 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java @@ -104,7 +104,7 @@ public class ThinkRaceProtocolDecoder extends BaseProtocolDecoder { position.setCourse(buf.readUnsignedByte()); position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()))); return position; diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java index ff33cb103..476d1d682 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -17,7 +17,6 @@ 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; @@ -36,11 +35,15 @@ import java.util.regex.Pattern; public class Tk103ProtocolDecoder extends BaseProtocolDecoder { - private final boolean decodeLow; + private boolean decodeLow; public Tk103ProtocolDecoder(Protocol protocol) { super(protocol); - decodeLow = Context.getConfig().getBoolean(Keys.PROTOCOL_DECODE_LOW.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + decodeLow = getConfig().getBoolean(Keys.PROTOCOL_DECODE_LOW.withPrefix(getProtocolName())); } private static final Pattern PATTERN = new PatternBuilder() diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 58c66031e..b76d5b307 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -320,7 +320,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { int lac = parser.nextHexInt(0); int cid = parser.nextHexInt(0); if (lac != 0 && cid != 0) { - position.setNetwork(new Network(CellTower.fromLacCid(lac, cid))); + position.setNetwork(new Network(CellTower.fromLacCid(getConfig(), lac, cid))); } position.set(Position.PREFIX_TEMP + 1, parser.next()); @@ -346,7 +346,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 2, parser.next()); position.setNetwork(new Network( - CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0)))); + CellTower.fromLacCid(getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); position.setValid(parser.next().equals("A")); position.set(Position.KEY_SATELLITES, parser.nextInt()); @@ -403,7 +403,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { int mcc = parser.nextInt(); cellTower = CellTower.from(mcc, mnc, lac, cid); } else { - cellTower = CellTower.fromLacCid(lac, cid); + cellTower = CellTower.fromLacCid(getConfig(), lac, cid); } position.set(Position.KEY_SATELLITES, parser.nextInt()); cellTower.setSignalStrength(parser.nextInt()); diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index 819c42471..b1ddc5203 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; 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; @@ -284,7 +283,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { if (hardware == 0x10A || hardware == 0x10B || hardware == 0x406) { position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); + CellTower.fromLacCid(getConfig(), buf.readUnsignedShort(), buf.readUnsignedShort()))); } else if (hardware == 0x407) { @@ -371,7 +370,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } - if (Context.getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { + if (getConfig().getBoolean(Keys.PROTOCOL_ACK.withPrefix(getProtocolName()))) { sendResponse(channel, remoteAddress, buf.getUnsignedShort(buf.writerIndex() - 6)); } diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java index 630fe5aed..b53a42ac3 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java @@ -18,7 +18,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import io.netty.channel.socket.nio.NioDatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -40,7 +39,11 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { public XirgoProtocolDecoder(Protocol protocol) { super(protocol); - form = Context.getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); + } + + @Override + protected void init() { + form = getConfig().getString(Keys.PROTOCOL_FORM.withPrefix(getProtocolName())); } public void setForm(String form) { diff --git a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java index 85e8e140f..b3f6493a8 100644 --- a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -18,7 +18,6 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; @@ -38,8 +37,11 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { public Xt2400ProtocolDecoder(Protocol protocol) { super(protocol); + } - String config = Context.getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); + @Override + protected void init() { + String config = getConfig().getString(Keys.PROTOCOL_CONFIG.withPrefix(getProtocolName())); if (config != null) { setConfig(config); } diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 1dddbb03b..35374a363 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,9 +1,39 @@ package org.traccar; +import org.traccar.config.Config; +import org.traccar.database.ConnectionManager; +import org.traccar.database.IdentityManager; +import org.traccar.database.MediaManager; +import org.traccar.database.StatisticsManager; +import org.traccar.model.Device; + +import static org.mockito.Mockito.*; + public class BaseTest { static { Context.init(new TestIdentityManager()); } + protected T inject(T decoder) throws Exception { + decoder.setConfig(new Config()); + var device = mock(Device.class); + when(device.getId()).thenReturn(1L); + var identityManager = mock(IdentityManager.class); + when(identityManager.getByUniqueId(any())).thenReturn(device); + decoder.setIdentityManager(identityManager); + decoder.setConnectionManager(mock(ConnectionManager.class)); + decoder.setStatisticsManager(mock(StatisticsManager.class)); + decoder.setMediaManager(mock(MediaManager.class)); + return decoder; + } + + protected T inject(T decoder) throws Exception { + return decoder; + } + + protected T inject(T encoder) throws Exception { + return encoder; + } + } diff --git a/src/test/java/org/traccar/protocol/AdmFrameDecoderTest.java b/src/test/java/org/traccar/protocol/AdmFrameDecoderTest.java index 1682ca56d..02d42447e 100644 --- a/src/test/java/org/traccar/protocol/AdmFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AdmFrameDecoderTest.java @@ -8,7 +8,7 @@ public class AdmFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AdmFrameDecoder(); + var decoder = inject(new AdmFrameDecoder()); verifyFrame( binary("38363931353330343235323337383400003728e000001402441d5f42c3711642930d000000c7000a461954f25fd82ed508000000000000000044000000010000000000140000"), diff --git a/src/test/java/org/traccar/protocol/AdmProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AdmProtocolDecoderTest.java index 7c8769925..810d53bf7 100644 --- a/src/test/java/org/traccar/protocol/AdmProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AdmProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AdmProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AdmProtocolDecoder(null); + var decoder = inject(new AdmProtocolDecoder(null)); verifyPosition(decoder, binary( "38363931353330343235323337383400003728e000001402441d5f42c3711642930d000000c7000a461954f25fd82ed508000000000000000044000000010000000000140000")); diff --git a/src/test/java/org/traccar/protocol/AisProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AisProtocolDecoderTest.java index f869ab8f3..36ea3d361 100644 --- a/src/test/java/org/traccar/protocol/AisProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AisProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AisProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AisProtocolDecoder(null); + var decoder = inject(new AisProtocolDecoder(null)); verifyPositions(decoder, text( "!AIVDM,2,1,8,A,53UlSb01l>Ei=H4KF218PTpv222222222222221?8h=766gB004410C2482>03410F56>03412F19>0441210000>034130FF>0441313A7>03410D30>04411F01B6>0341048C>04410C1C98];"), diff --git a/src/test/java/org/traccar/protocol/ArnaviBinaryProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ArnaviBinaryProtocolDecoderTest.java index f2940de59..f96da5203 100644 --- a/src/test/java/org/traccar/protocol/ArnaviBinaryProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ArnaviBinaryProtocolDecoderTest.java @@ -8,9 +8,7 @@ public class ArnaviBinaryProtocolDecoderTest extends ProtocolTest { @Test public void testHeader1Decode() throws Exception { - ArnaviBinaryProtocolDecoder decoder; - - decoder = new ArnaviBinaryProtocolDecoder(null); + var decoder = inject(new ArnaviBinaryProtocolDecoder(null)); verifyNull(decoder, binary( "ff22f30c45f5c90f0300")); @@ -23,9 +21,7 @@ public class ArnaviBinaryProtocolDecoderTest extends ProtocolTest { @Test public void testHeader2Decode() throws Exception { - ArnaviBinaryProtocolDecoder decoder; - - decoder = new ArnaviBinaryProtocolDecoder(null); + var decoder = inject(new ArnaviBinaryProtocolDecoder(null)); verifyNull(decoder, binary( "ff23f30c45f5c90f0300")); diff --git a/src/test/java/org/traccar/protocol/ArnaviFrameDecoderTest.java b/src/test/java/org/traccar/protocol/ArnaviFrameDecoderTest.java index 3f495731a..92ca5d2b0 100644 --- a/src/test/java/org/traccar/protocol/ArnaviFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ArnaviFrameDecoderTest.java @@ -8,7 +8,7 @@ public class ArnaviFrameDecoderTest extends ProtocolTest { @Test public void testDecodeValidPackets() throws Exception { - var decoder = new ArnaviFrameDecoder(); + var decoder = inject(new ArnaviFrameDecoder()); verifyFrame( binary("2441562c563344492c38353136342c3231342c2d312c31392c30303030344634462c30303030303935452c30433030303030322c3836333037313031333034313631382c38393939373031353630333832353236363232462c2a3039"), diff --git a/src/test/java/org/traccar/protocol/ArnaviTextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ArnaviTextProtocolDecoderTest.java index 9e9047be4..e27367119 100644 --- a/src/test/java/org/traccar/protocol/ArnaviTextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ArnaviTextProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ArnaviTextProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ArnaviTextProtocolDecoder(null); + var decoder = inject(new ArnaviTextProtocolDecoder(null)); verifyPosition(decoder, buffer( "$AV,V4,999999,12487,2277,203,65534,0,0,193,65535,65535,65535,65535,1,13,80.0,56.1,200741,5950.6773N,03029.1043E,300.0,360.0,121012,65535,65535,65535,SF*6E")); diff --git a/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java index 3376fa3f0..2d8798dff 100644 --- a/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AstraProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AstraProtocolDecoder(null); + var decoder = inject(new AstraProtocolDecoder(null)); verifyPositions(decoder, binary( "4b00700529c0c265976b8202cba9ff00676d864554a9c30000000020073401006436000300030008000000000000a0000100001920c43d00009600428302cba9ff00676d864554aa3e000000002007240100643b000300020008000000000000b0000100001920c43d00009600420f0e")); diff --git a/src/test/java/org/traccar/protocol/At2000FrameDecoderTest.java b/src/test/java/org/traccar/protocol/At2000FrameDecoderTest.java index 0782c2d34..773a8f7f5 100644 --- a/src/test/java/org/traccar/protocol/At2000FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/At2000FrameDecoderTest.java @@ -8,7 +8,7 @@ public class At2000FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new At2000FrameDecoder(); + var decoder = inject(new At2000FrameDecoder()); verifyFrame( binary("01012f00000000000000000000000000003335363137333036343430373439320fad981997ae8e031fe10c0ea7641903ca32c0331df467233d2a9cd886fbeef8"), diff --git a/src/test/java/org/traccar/protocol/AtrackFrameDecoderTest.java b/src/test/java/org/traccar/protocol/AtrackFrameDecoderTest.java index 77e90ca53..958814e53 100644 --- a/src/test/java/org/traccar/protocol/AtrackFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AtrackFrameDecoderTest.java @@ -8,7 +8,7 @@ public class AtrackFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AtrackFrameDecoder(); + var decoder = inject(new AtrackFrameDecoder()); verifyFrame( binary("4052698c032a924f000147027fe5d7425f642e56060f031847bb68cb500719e26752c25bebc11c7fddce2b8ed4eff4ed863b187cc6653b5b1c1fc6803884d21aeeedae2ec6e72781d97e95b965610c1d107e5400cd5a7b7b3b592e676091c6a5893d80af9b3c63ae4de20d6e5bc60440bf2c299fbabfe268039d558e4b8589dd5173c926b7f51b916ba29f21d46ff9170793fe450072d691896e114fddce4fd29f7f2f9b74e41ca83814015e8a00ffd1f9bd475e2a44624e074a009455ab5628e39fce8036a09368cf1d2ba0d2653b979c0a00e9edc82335a56d1ee6071401d468b0f4cd761a743d011401d15b4636015721870dd0500695b2edabeabf2f4a00a514645cc83a739ad165f320c1ed401617a0a2800a2803ffd2faa68a004660aa598e00acd8f4d866d54eab3c7994284881fe11ebf5e68034e8a0086e674850927f0ae2bc4dafa5844659674451d39e49a00e1dae23d76ed67bb72211d109e4d5bd756da3b68a4b755021e30076a00cf31431a064e41e6a19a68d5396518f7a00f1ff008bfe27f31068766dbb7e1a723d3fbbf8d79aeb764748b489662be7ccbbb6820e07d4500734caa727765aa32ac0720e28026b4bb9ed7ccf2594798bb5b2a0f1f8f4a82800a2803fffd3f9b97352ae02e45004c808e4f7a997823bd005e86600618f26b7b4a9cab819fa500767a749b9403cd74162b903de803acd1e3c28aebf4d4c81401d05a4441fad682444738a00b712f2055f03e502802b14c5dffbc2ac106343ed4012a905411e94b40051401fffd4faa6992488980c793d0773400d54676df2f1e8b9e054b400564ebb77750c463b442d2119247f08f53e9401e7da85d6a12cd221d427217a856c60fe15caea9689292f2832bfac8777f3a00e67538ef150ff00665d9b4b95fba4aee46f623fa8ae26fbe24f88b49b87d3b5bd2a12e38ca3950e3d41e7228008be2ac02d423dadc09071c1047e791fcab96d77c79acdf92969279113f1c1cb7e7401876c4c939b8ba73230e5998e49ac4d66ee6bebd796462ddb9f4ed40140a12339e9dea225b1824d0025140051401fffd5f9bc676f6a7ae4af6e280255cf5c7153a7b0a0052d8715bba64bf32f39a00ed74694902bb1d306e65c500763a5afca2baed2"), diff --git a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java index 4a66dbf58..b6b09fc25 100644 --- a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AtrackProtocolDecoder(null); + var decoder = inject(new AtrackProtocolDecoder(null)); verifyNull(decoder, binary( "4052698c032a924f000147027fe5d7425f642e56060f031847bb68cb500719e26752c25bebc11c7fddce2b8ed4eff4ed863b187cc6653b5b1c1fc6803884d21aeeedae2ec6e72781d97e95b965610c1d107e5400cd5a7b7b3b592e676091c6a5893d80af9b3c63ae4de20d6e5bc60440bf2c299fbabfe268039d558e4b8589dd5173c926b7f51b916ba29f21d46ff9170793fe450072d691896e114fddce4fd29f7f2f9b74e41ca83814015e8a00ffd1f9bd475e2a44624e074a009455ab5628e39fce8036a09368cf1d2ba0d2653b979c0a00e9edc82335a56d1ee6071401d468b0f4cd761a743d011401d15b4636015721870dd0500695b2edabeabf2f4a00a514645cc83a739ad165f320c1ed401617a0a2800a2803ffd2faa68a004660aa598e00acd8f4d866d54eab3c7994284881fe11ebf5e68034e8a0086e674850927f0ae2bc4dafa5844659674451d39e49a00e1dae23d76ed67bb72211d109e4d5bd756da3b68a4b755021e30076a00cf31431a064e41e6a19a68d5396518f7a00f1ff008bfe27f31068766dbb7e1a723d3fbbf8d79aeb764748b489662be7ccbbb6820e07d4500734caa727765aa32ac0720e28026b4bb9ed7ccf2594798bb5b2a0f1f8f4a82800a2803fffd3f9b97352ae02e45004c808e4f7a997823bd005e86600618f26b7b4a9cab819fa500767a749b9403cd74162b903de803acd1e3c28aebf4d4c81401d05a4441fad682444738a00b712f2055f03e502802b14c5dffbc2ac106343ed4012a905411e94b40051401fffd4faa6992488980c793d0773400d54676df2f1e8b9e054b400564ebb77750c463b442d2119247f08f53e9401e7da85d6a12cd221d427217a856c60fe15caea9689292f2832bfac8777f3a00e67538ef150ff00665d9b4b95fba4aee46f623fa8ae26fbe24f88b49b87d3b5bd2a12e38ca3950e3d41e7228008be2ac02d423dadc09071c1047e791fcab96d77c79acdf92969279113f1c1cb7e7401876c4c939b8ba73230e5998e49ac4d66ee6bebd796462ddb9f4ed40140a12339e9dea225b1824d0025140051401fffd5f9bc676f6a7ae4af6e280255cf5c7153a7b0a0052d8715bba64bf32f39a00ed74694902bb1d306e65c500763a5afca2baed2")); @@ -111,7 +111,7 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeCustom() throws Exception { - var decoder = new AtrackProtocolDecoder(null); + var decoder = inject(new AtrackProtocolDecoder(null)); decoder.setCustom(true); diff --git a/src/test/java/org/traccar/protocol/AuroProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AuroProtocolDecoderTest.java index fbe3ad0a3..368f7ed4c 100644 --- a/src/test/java/org/traccar/protocol/AuroProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AuroProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AuroProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AuroProtocolDecoder(null); + var decoder = inject(new AuroProtocolDecoder(null)); verifyPosition(decoder, text( "M0028T0000816398975I357325031465123E00001W*****110620150437000068DA#RD01DA240000000001+100408425+013756121100620152137231112240330004400")); diff --git a/src/test/java/org/traccar/protocol/AustinNbProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AustinNbProtocolDecoderTest.java index 0be22b333..30152e94c 100644 --- a/src/test/java/org/traccar/protocol/AustinNbProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AustinNbProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AustinNbProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AustinNbProtocolDecoder(null); + var decoder = inject(new AustinNbProtocolDecoder(null)); verifyPosition(decoder, text( "48666666666;2017-01-01 16:31:01;52,1133308410645;21,1000003814697;310;120;2292;1;ORANGE")); diff --git a/src/test/java/org/traccar/protocol/AutoFonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AutoFonProtocolDecoderTest.java index 3e64defdb..8e17d5673 100644 --- a/src/test/java/org/traccar/protocol/AutoFonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AutoFonProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class AutoFonProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AutoFonProtocolDecoder(null); + var decoder = inject(new AutoFonProtocolDecoder(null)); verifyNull(decoder, binary( "10556103592310314825728F")); diff --git a/src/test/java/org/traccar/protocol/AutoGradeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AutoGradeProtocolDecoderTest.java index 697ac8a06..7f837451c 100644 --- a/src/test/java/org/traccar/protocol/AutoGradeProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AutoGradeProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AutoGradeProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AutoGradeProtocolDecoder(null); + var decoder = inject(new AutoGradeProtocolDecoder(null)); verifyPosition(decoder, text( "(000000001637868324027912356171116A2250.7611N07556.9425E000.9024427197.36\u008eA0000B0000C0000D0000E0000K0000L0000M0000N0000O0000)")); diff --git a/src/test/java/org/traccar/protocol/AutoTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AutoTrackProtocolDecoderTest.java index 64a7459ce..51bbd0d8c 100644 --- a/src/test/java/org/traccar/protocol/AutoTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AutoTrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class AutoTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AutoTrackProtocolDecoder(null); + var decoder = inject(new AutoTrackProtocolDecoder(null)); verifyNull(decoder, binary( "f1f1f1f1330c00201007090006de7200000000daa3")); diff --git a/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java index 6138711aa..7f41d6b47 100644 --- a/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class AvemaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new AvemaProtocolDecoder(null); + var decoder = inject(new AvemaProtocolDecoder(null)); 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"), diff --git a/src/test/java/org/traccar/protocol/Avl301ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Avl301ProtocolDecoderTest.java index fb1984d87..1da432cea 100644 --- a/src/test/java/org/traccar/protocol/Avl301ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Avl301ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Avl301ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Avl301ProtocolDecoder(null); + var decoder = inject(new Avl301ProtocolDecoder(null)); verifyNull(decoder, binary( "244c0f086058500087335500010d0a")); diff --git a/src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java index 6b9c71b0e..ea3b38e7d 100644 --- a/src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/B2316ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class B2316ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new B2316ProtocolDecoder(null); + var decoder = inject(new B2316ProtocolDecoder(null)); verifyPositions(decoder, false, text( "{\"imei\":\"866349041783600\",\"data\":[{\"tm\":1631162952,\"wn\":7},{\"tm\":1631158729,\"ic\":\"89883030000059398609\",\"ve\":\"B2316.TAU.U.TH01\"},{\"tm\":1631158805,\"te\":\"312,363\",\"st\":0,\"ba\":3,\"sn\":80},{\"tm\":1631158829,\"ci\":\"505,1,8218,133179149,-108\"},{\"tm\":1631162956,\"wi\":\"101331c17f4f,-74;f46bef7953bb,-81;b09575cff1c8,-86;e2b9e5d61a7a,-88;b0ee7b4dee2f,-88;e0b9e5d61a77,-89;f66bef7953b9,-89;\",\"te\":\"335,366\",\"hr\":58,\"bp\":\"113,73\",\"st\":0,\"ba\":3,\"sn\":60},{\"tm\":1631162968,\"ci\":\"505,1,8218,133179149,-105\"}]}")); diff --git a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java index 544d49967..4117833c0 100644 --- a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class BceProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new BceProtocolDecoder(null); + var decoder = inject(new BceProtocolDecoder(null)); verifyNull(decoder, binary( "3ab90b71bc1503000300c10bff11")); diff --git a/src/test/java/org/traccar/protocol/BlackKiteProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BlackKiteProtocolDecoderTest.java index 3fdac8479..2fb93f2a9 100644 --- a/src/test/java/org/traccar/protocol/BlackKiteProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BlackKiteProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class BlackKiteProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new BlackKiteProtocolDecoder(null); + var decoder = inject(new BlackKiteProtocolDecoder(null)); verifyNull(decoder, binary( "01150003313131313131313131313131313131209836055605BA")); diff --git a/src/test/java/org/traccar/protocol/BlueProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BlueProtocolDecoderTest.java index 4e74adf38..1de542e24 100644 --- a/src/test/java/org/traccar/protocol/BlueProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BlueProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class BlueProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new BlueProtocolDecoder(null); + var decoder = inject(new BlueProtocolDecoder(null)); verifyAttribute(decoder, binary( "AA0056860080E3E79E0C811F80000114020207170520011F00407F8005EE1938113B270000000000000000140202071705005AC7A621121F0002000100B7000080110000000000001A3A0000000001F400000000000078"), diff --git a/src/test/java/org/traccar/protocol/BoxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BoxProtocolDecoderTest.java index 5b639e12b..0a19eb3b0 100644 --- a/src/test/java/org/traccar/protocol/BoxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BoxProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class BoxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new BoxProtocolDecoder(null); + var decoder = inject(new BoxProtocolDecoder(null)); verifyNull(decoder, text( "H,BT,358281002435893,081028142432,F5813D19,6D6E6DC2")); diff --git a/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java index 6fb14b902..fbb530e7f 100644 --- a/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class C2stekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new C2stekProtocolDecoder(null); + var decoder = inject(new C2stekProtocolDecoder(null)); verifyPosition(decoder, text( "PA$867965024889327$D#220222#135059#0#+37.98995#+23.85141#0.00#69.2#0.0#0000#000#8#00#sz-w1001#B2600$AP")); diff --git a/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java index 79d27e2ab..1a8431f23 100644 --- a/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CalAmpProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CalAmpProtocolDecoder(null); + var decoder = inject(new CalAmpProtocolDecoder(null)); verifyPosition(decoder, binary( "830547643586340101010400105f9c39ba5f9c302eeb36d5bddf39df700000000000000000003400040321ff9f4f0087080200001c30783330304544383946333335303139303030303030343637450d0a")); diff --git a/src/test/java/org/traccar/protocol/CarTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CarTrackProtocolDecoderTest.java index dd96c2585..d12d4aa9f 100644 --- a/src/test/java/org/traccar/protocol/CarTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CarTrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CarTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CarTrackProtocolDecoder(null); + var decoder = inject(new CarTrackProtocolDecoder(null)); verifyNull(decoder, text( "$$020040????????&A0000")); diff --git a/src/test/java/org/traccar/protocol/CarscopProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CarscopProtocolDecoderTest.java index b1fe69bac..71137cacf 100644 --- a/src/test/java/org/traccar/protocol/CarscopProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CarscopProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CarscopProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CarscopProtocolDecoder(null); + var decoder = inject(new CarscopProtocolDecoder(null)); verifyNull(decoder, text( "*170821223045UB00HSO")); diff --git a/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java index f90fbe5ba..1add623b7 100644 --- a/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class CastelProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CastelProtocolDecoder(null); + var decoder = inject(new CastelProtocolDecoder(null)); verifyAttribute(decoder, binary( "40403a00043231334744503230313830323133343300000000a002000001000001012011004d414c43333831434d4b4d353637313438c8fc0d0a"), diff --git a/src/test/java/org/traccar/protocol/CautelaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CautelaProtocolDecoderTest.java index fe8586068..4022d688b 100644 --- a/src/test/java/org/traccar/protocol/CautelaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CautelaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CautelaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CautelaProtocolDecoder(null); + var decoder = inject(new CautelaProtocolDecoder(null)); verifyPosition(decoder, text( "20,010907000000,14,02,18,16.816667,96.166667,1325,S,*2E")); diff --git a/src/test/java/org/traccar/protocol/CellocatorFrameDecoderTest.java b/src/test/java/org/traccar/protocol/CellocatorFrameDecoderTest.java index 04a0f74d5..c266dd1f4 100644 --- a/src/test/java/org/traccar/protocol/CellocatorFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CellocatorFrameDecoderTest.java @@ -8,7 +8,7 @@ public class CellocatorFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CellocatorFrameDecoder(); + var decoder = inject(new CellocatorFrameDecoder()); verifyFrame( binary("4D4347500BA9880B00C80A7E003800000000000806000001210A14000613000000000D4457A5F71442AC02E80300000100040707000011171408060E1C08000100000200020000FD"), diff --git a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java index 3ae5350f2..7e96b073b 100644 --- a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CellocatorProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CellocatorProtocolDecoder(null); + var decoder = inject(new CellocatorProtocolDecoder(null)); verifyPosition(decoder, binary( "4D43475000856308000004B2DE1F04009E00200100000000696CF7AB002F1A00000000000000325C000402069BFDE70857E22502F41C000036000000DF0B0932100B09DC0719")); diff --git a/src/test/java/org/traccar/protocol/CguardProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CguardProtocolDecoderTest.java index a7ed0e754..835ab5fe5 100644 --- a/src/test/java/org/traccar/protocol/CguardProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CguardProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CguardProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CguardProtocolDecoder(null); + var decoder = inject(new CguardProtocolDecoder(null)); verifyNull(decoder, text( "IDRO:354868050655283")); diff --git a/src/test/java/org/traccar/protocol/CityeasyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CityeasyProtocolDecoderTest.java index 07d6368ab..0c1fc1f5d 100644 --- a/src/test/java/org/traccar/protocol/CityeasyProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CityeasyProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class CityeasyProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CityeasyProtocolDecoder(null); + var decoder = inject(new CityeasyProtocolDecoder(null)); verifyNotNull(decoder, binary( "545400853575570249020100033b3430342c34352c31303638312c31313632312c33352c31303638312c31313632322c32332c31303638312c32383938332c32332c31303638312c31313632332c32312c31303638312c32333338312c31372c31303638312c32323538332c31372c31303638312c32363434312c31330000000d352e0d0a")); diff --git a/src/test/java/org/traccar/protocol/ContinentalProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ContinentalProtocolDecoderTest.java index 2924d2c4d..6ac2ae01d 100644 --- a/src/test/java/org/traccar/protocol/ContinentalProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ContinentalProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ContinentalProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ContinentalProtocolDecoder(null); + var decoder = inject(new ContinentalProtocolDecoder(null)); verifyPosition(decoder, binary( "5356003216001eb48505025b4001e90f7f18ce0f00522200400001015b4001e9000e820100000c24000100014e0400736a7a"), diff --git a/src/test/java/org/traccar/protocol/CradlepointProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CradlepointProtocolDecoderTest.java index 1e3023b39..f95bfb54d 100644 --- a/src/test/java/org/traccar/protocol/CradlepointProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CradlepointProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class CradlepointProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new CradlepointProtocolDecoder(null); + var decoder = inject(new CradlepointProtocolDecoder(null)); verifyPosition(decoder, text( "356526070063940,0,4337.19009,N,11612.34705,W,0.0,277.2,AT&T,,,-79,,-14.0,")); diff --git a/src/test/java/org/traccar/protocol/DingtekFrameDecoderTest.java b/src/test/java/org/traccar/protocol/DingtekFrameDecoderTest.java index 6236410b3..c63775858 100644 --- a/src/test/java/org/traccar/protocol/DingtekFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DingtekFrameDecoderTest.java @@ -8,7 +8,7 @@ public class DingtekFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DingtekFrameDecoder(); + var decoder = inject(new DingtekFrameDecoder()); verifyFrame( binary("383030303031303131453032383830303138303030303030303030313545303038303545433430303031313836383832323034303130343433303831"), diff --git a/src/test/java/org/traccar/protocol/DingtekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DingtekProtocolDecoderTest.java index 8b3d07c22..7e5f68e05 100644 --- a/src/test/java/org/traccar/protocol/DingtekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DingtekProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DingtekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DingtekProtocolDecoder(null); + var decoder = inject(new DingtekProtocolDecoder(null)); verifyPosition(decoder, text( "800001011e0692001a00000000016e008027c40000186962703655111781")); diff --git a/src/test/java/org/traccar/protocol/DishaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DishaProtocolDecoderTest.java index 4492b3ed0..3faccd7ea 100644 --- a/src/test/java/org/traccar/protocol/DishaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DishaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DishaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DishaProtocolDecoder(null); + var decoder = inject(new DishaProtocolDecoder(null)); verifyPosition(decoder, text( "$A#A#864161028848856#A#053523#010216#2232.7733#N#08821.1940#E#002.75#038.1#09#00.8#1800#0#000#0000#9999#11.7#285.7#0001*")); diff --git a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java index 31d0efa12..99760546f 100644 --- a/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DmtHttpProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class DmtHttpProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DmtHttpProtocolDecoder(null); + var decoder = inject(new DmtHttpProtocolDecoder(null)); verifyAttributes(decoder, request(HttpMethod.POST, "/", buffer("{\"date\":\"2021-12-12T16:04:52Z\",\"device\":{\"sn\":\"416581\",\"prod\":85,\"rev\":1,\"fw\":\"1.12\",\"iccid\":\"89011702278612797427\",\"imei\":\"351358810439486\"},\"sqn\":1549,\"reason\":42,\"counters\":[{\"id\":0,\"val\":5304},{\"id\":3,\"val\":3200},{\"id\":4,\"val\":5066},{\"id\":128,\"val\":1},{\"id\":129,\"val\":8},{\"id\":130,\"val\":0},{\"id\":131,\"val\":0},{\"id\":132,\"val\":0},{\"id\":134,\"val\":1},{\"id\":138,\"val\":0},{\"id\":139,\"val\":36},{\"id\":142,\"val\":1629023},{\"id\":145,\"val\":0},{\"id\":146,\"val\":1}]}"))); diff --git a/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java index 82a4cd5ff..9c14a1ebe 100644 --- a/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DmtProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DmtProtocolDecoder(null); + var decoder = inject(new DmtProtocolDecoder(null)); verifyNull(decoder, binary( "0255003300001b00003335333232393032373533393235310038393931353030303030303030313330343539340000000403041910780603")); diff --git a/src/test/java/org/traccar/protocol/DolphinProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DolphinProtocolDecoderTest.java index 0215973e8..b9e3da67d 100644 --- a/src/test/java/org/traccar/protocol/DolphinProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DolphinProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DolphinProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DolphinProtocolDecoder(null); + var decoder = inject(new DolphinProtocolDecoder(null)); verifyPositions(decoder, binary( "ababff8f0300000100000100e03c0b86c70e03005c0f0000ab4cd12d0aa9010d0d7f0e4215f6fe6c421d00b0ce4420122daa9a9042359a99f9413806455e53fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa0662404801010ce41bb8f4cc2ad801fe98f3030893dd9a010001019299f303155400000007b401000000000072ac01b99401f8de8a0adc03900e0049000003004bfa010aa7010d4f7f0e421505ff6c421dcd1cce4420112d3ef984423552b89e413806456053fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e4201010ce41bd8f4cc2a20ff98f3030193dd9a010001019399f30315420000000000000000000072ad018f950181df8a0aee03cd0d004b000003004bfa010aa7010da67f0e42154fff6c421d3393cd4420112d073c9942358fc2df413806456253fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e4c010111f51d88f5cc2a308199f3030293dd9a010001019599f303154c0000000000000000000072ad01ef95018bdf8a0aee03d30d004a000003004bfa010aa9010dfd800e421525006d421d3373d04420102da5b7aa4235ec51c4413806456853fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa0662405501010ef01db0f6cc2aa8018899f3030793dd9a010001019c99f3031555000000068a010000000000739d01df9501acdf8a0ac0028a150031000003004bfa010aa8010d3b830e421561016d421dcddcd04420102d8edda94235cdccbe413806457353fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623f5401010ef01db8f8cc2a88029499f3030c93dd9a01000101a899f303155500000004480000000000728a018f9501e5df8a0aa9018d280015000003004bfa010aa8010ddd850e4215b3026d421dcd3cd04420112d2e9ba942359a99af413806458053fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623f5401010df01df0facc2ab802a199f3030d93dd9a01000101b599f303155500000005760000000000728b01f59401a2e08a0a9b01c12b0018000003004bfa010aa9010d4a870e421554036d421d66d6cf4420112d5f29a842355c8faa413806458753fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa0662405401010dea1d98fccc2aa801a899f3030793dd9a01000101bc99f303155400000007a4010000000000719701b29401bae08a0a9202be180026000003004bfa010aa7010da7870e421591036d421d33d3cf4420112d6329a942353333a7413806458953fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e5401010df51dc8fccc2a30aa99f3030293dd9a01000101be99f3031554000000022c0000000000719901db9401c3e08a0aae02a016002b000003004bfa010aa7010d1a880e4215b6036d421d33e3cf4420112ddc45aa423514aea3413806458b53fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e5501010df51df8fccc2a30ac99f3030293dd9a01000101c099f303155500000002320000000000719e01f69401d1e08a0a9f02b3170031000003004bfa010aa8010d50890e42154d046d421d3363d04420102da0b7a94235d7a3a2413806459253fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623f5401010edf1d88fecc2a9001b399f3030793dd9a01000101c799f303155400000000000000000000729a01e69501f7e08a0ab0028e16002d000003004bfa010aa9010d188c0e421573056d421d00c0ce4420102d300c84423514ae7741380645a053fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06624042010110da1dd080cd2ac802c199f3030e93dd9a01000101d599f303155500000009e2010000000000729801b19501afe18a0a97029018002a000003004bfa010aa7010d528c0e42159d056d421d3313cf4420102dfec98c423552b8c241380645a053fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e46010110da1df080cd2a20c299f3030193dd9a01000101d699f303154600000000000000000000729701df9501b8e18a0aa002b9170029000003004bfa010aa9010d198f0e42159e066d421d9a49d04420112dfae6a642359a999941380645ad53fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06624053010111e51da883cd2ab802cf99f3030d93dd9a01000101e399f30315540000000ca4020000000000729601c49501f1e18a0a9102dc180028000003004bfa010aa7010da68f0e4215e9066d421d9a19d044200f2d83dda74235ec519441380645b153fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e53010111e51df083cd2a48d299f3030393dd9a01000101e699f303155300000003400000000000729701de950183e28a0a8e02ff180028000003004bfa010aa7010d40900e42151a076d421d33c3cf4420102d717e9b423548e15e41380645b453fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e4d010110e51db884cd2a48d599f3030393dd9a01000101e999f303154d00000003420000000000729801bf950191e28a0a9a02f117002a000003004bfa010aa7010d5f900e42153c076d421d66c6cf44200f2de3028d4235713daa41380645b553fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e46010110da1dc884cd2a10d699f3030193dd9a01000101ea99f303154600000001120000000000729901bf950191e28a0a98029318002b000003004bfa010aa7010dae900e42153d076d421d9ad9cf44200f2d324fa342357b144241380645b653fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e51010110da1de884cd2a20d799f3030193dd9a01000101eb99f303155100000000000000000000729b01a5950196e28a0aa2029b17002c000003004bfa010aa7010d08910e42157e076d421d33b3cf4420102d51b79a42357b14b241380645b853fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623e4d010110da1d9885cd2a30d999f3030293dd9a01000101ed99f3031552000000022c0000000000729b01ca95019be28a0ab602e815002f000003004bfa010aa9010d3b930e42153f086d421d9a99d044200f2d5a3ca9423552b88441380645c153fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06624054010110f51d9087cd2af801e499f3030b93dd9a01000101f899f30315540000000bfa010000000000729901cf9501cee28a0ac502f814002e000003004bfa010aa9010df1950e421558096d421d6646d24420102da3a4a842357b149441380645cf53fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa0662405401010eea1dc889cd2ab802f199f3030d93dd9a01000101859af303155500000008be010000000000729901c7950190e38a0a9c02da17002c000003004bfa010aa9010dcf970e4215260a6d421d6676d34420112d653cab423552b89e41380645d853fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa0662405501010efa1ba08bcd2ad801fa99f3030993dd9a010001018e9af303155600000007a8010000000000729e01bb9501bae38a0ac00284150031000003004bfa010aa8010de89a0e4215510b6d421d00a0d44420112d1aaea74235cdcc6841380645e653fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06623f53010110f51d808ecd2ae002899af3030f93dd9a010001019d9af30315550000000460000000000073a401e59501fce38a0a9003e510003e000003004bfa010aa9010d6b9c0e4215b00b6d421d00b0d44420112dd46bac423585eb0541380645ed53fc5f48015a41050a0b1e29323334353637464850649601a401a601aa01ab01ad01b401b501b601b701b801c905ca05cb05cd05d105d205e605e705ef059c069e06a206a906aa06624056010110ea1da88fcd2aa801919af3030893dd9a01000101a59af303155600000008a801000000000073a201a19501a1e48a0a8103ce110038000003004bfa01")); diff --git a/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java index fc18b0560..7e3ec0706 100644 --- a/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Dsf22FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Dsf22FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Dsf22FrameDecoder(); + var decoder = inject(new Dsf22FrameDecoder()); verifyFrame( binary("4642000101A8EE5F0ECA5FF421B33F524E32610401"), diff --git a/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java index 4089c208c..2e52b950d 100644 --- a/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Dsf22ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Dsf22ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Dsf22ProtocolDecoder(null); + var decoder = inject(new Dsf22ProtocolDecoder(null)); verifyPositions(decoder, binary( "4642a82d01c8f6aa1af1792c0c1411eb61001e0000")); diff --git a/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java b/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java index 46f32a8ae..f74a40d13 100644 --- a/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DualcamFrameDecoderTest.java @@ -8,7 +8,7 @@ public class DualcamFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DualcamFrameDecoder(); + var decoder = inject(new DualcamFrameDecoder()); verifyFrame( binary("000000050001403a4abaa31444000400"), diff --git a/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java index 3dd11bdf7..a61f20c13 100644 --- a/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DualcamProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DualcamProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DualcamProtocolDecoder(null); + var decoder = inject(new DualcamProtocolDecoder(null)); verifyNull(decoder, binary( "000000050001403a4abaa31444000400")); diff --git a/src/test/java/org/traccar/protocol/DwayProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DwayProtocolDecoderTest.java index 368f8b4ac..1cdd82664 100644 --- a/src/test/java/org/traccar/protocol/DwayProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/DwayProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class DwayProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new DwayProtocolDecoder(null); + var decoder = inject(new DwayProtocolDecoder(null)); verifyPosition(decoder, text( "AA55,36,10024,1,171025,161055,36.0294,-79.7881,201, 2.5,111,1000,0000,00000,3578,0,0,0,D")); diff --git a/src/test/java/org/traccar/protocol/EasyTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EasyTrackProtocolDecoderTest.java index 5fda7fb28..ef319449e 100644 --- a/src/test/java/org/traccar/protocol/EasyTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EasyTrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EasyTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EasyTrackProtocolDecoder(null); + var decoder = inject(new EasyTrackProtocolDecoder(null)); verifyNotNull(decoder, text( "*ET,354522180593498,JZ,0,20222,262,724,4#")); diff --git a/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java index c1cc3c39a..ec1467c09 100644 --- a/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EelinkProtocolDecoder(null); + var decoder = inject(new EelinkProtocolDecoder(null)); verifyPositions(decoder, binary( "454c029249a50354679090044671676712004321315f3cf43503fc94d3760c79328a0129000000000a01f9000190330905580d2e046f118a04ec00000000ccc7086c02fe000000000000000000000000000000000000676712004321325f3cf43e03fc94d3760c79328a0129000000000901f9000190330905580d2e046f117b04ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321335f3cf44703fc94d3760c79328a0129000000000901f9000190330905580d2e046f117f04ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321345f3cf45303fc94d3760c79328a0129000000000901f9000190330905580d2e046f119d04ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321355f3cf45c03fc94d3760c79328a0129000000000801f9000190330905580d2e046f11a304ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321365f3cf46603fc94d3760c79328a0129000000000801f9000190330905580d2e046f118804df00000000ccc7086d02ff000000000000000000000000000000000000676712004321375f3cf47103fc94d3760c79328a0129000000000901f9000190330905580d2e046f119704ec00000000ccc7086d02ff000000000000000000000000000000000000676712004321385f3cf47a03fc94d3760c79328a0129000000000901f9000190330905580d2e046f118204ec00000000ccc7086e0300000000000000000000000000000000000000676712004321395f3cf48303fc94d3760c79328a0129000000000901f9000190330905580d2e046f117604df00000000ccc7086e0300000000000000000000000000000000000000")); diff --git a/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java index a1acb1e9d..dde71d1e7 100644 --- a/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java @@ -8,7 +8,7 @@ public class EgtsFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EgtsFrameDecoder(); + var decoder = inject(new EgtsFrameDecoder()); verifyFrame( binary("0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2"), diff --git a/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java index dcf70bcae..0f5a40605 100644 --- a/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EgtsProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeWithObjectId() throws Exception { - var decoder = new EgtsProtocolDecoder(null); + var decoder = inject(new EgtsProtocolDecoder(null)); verifyNull(decoder, binary( "0100020b002300020001871c00020000010105190000ab0800006247396e615734366347467a63336476636d513daadf")); @@ -31,7 +31,7 @@ public class EgtsProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeWithAuth() throws Exception { - var decoder = new EgtsProtocolDecoder(null); + var decoder = inject(new EgtsProtocolDecoder(null)); verifyNull(decoder, binary( "0100010b002200c06401f21700c1640171360d00010101140071360d000238363539303500000000000000000047fc")); diff --git a/src/test/java/org/traccar/protocol/EnforaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnforaProtocolDecoderTest.java index 14e982e39..2d2a211c3 100644 --- a/src/test/java/org/traccar/protocol/EnforaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnforaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EnforaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EnforaProtocolDecoder(null); + var decoder = inject(new EnforaProtocolDecoder(null)); verifyNull(decoder, binary( "000A08002020202020303131303730303030353730323637")); diff --git a/src/test/java/org/traccar/protocol/EnnfuProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnnfuProtocolDecoderTest.java index 4afa5921f..0134e8052 100644 --- a/src/test/java/org/traccar/protocol/EnnfuProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnnfuProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EnnfuProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EnnfuProtocolDecoder(null); + var decoder = inject(new EnnfuProtocolDecoder(null)); verifyPosition(decoder, text( "Ennfu:354679095321652,041504.00,A,3154.86654,N,11849.08737,E,0.053,,080121,20,3.72,21.4,V0.01")); diff --git a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java index 0809a1e9a..50db6c743 100644 --- a/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EnvotechProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EnvotechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EnvotechProtocolDecoder(null); + var decoder = inject(new EnvotechProtocolDecoder(null)); verifyPosition(decoder, text( "$80IVM,03,E002215,E002215,110422061936,672763902,126423,0180,000000,00018600,0.0000'11042206193710406325S03966094E000118*42D6#")); diff --git a/src/test/java/org/traccar/protocol/EsealProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EsealProtocolDecoderTest.java index d0d9e3c41..2d9b19b70 100644 --- a/src/test/java/org/traccar/protocol/EsealProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EsealProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class EsealProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EsealProtocolDecoder(null); + var decoder = inject(new EsealProtocolDecoder(null)); verifyPosition(decoder, text( "##S,eSeal,1000821,256,3.0.6,Normal,34,2017-08-31,08:14:40,15,A,25.708828N 100.372870W,10,0,Close,0.71,0:0:3:0,3.8,-73,E##")); diff --git a/src/test/java/org/traccar/protocol/EskyFrameDecoderTest.java b/src/test/java/org/traccar/protocol/EskyFrameDecoderTest.java index c3926c8d7..f808cd4a8 100644 --- a/src/test/java/org/traccar/protocol/EskyFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EskyFrameDecoderTest.java @@ -8,7 +8,7 @@ public class EskyFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EskyFrameDecoder(); + var decoder = inject(new EskyFrameDecoder()); verifyNull( decoder.decode(null, null, binary("00"))); diff --git a/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java index ace55f934..678007f5c 100644 --- a/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class EskyProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new EskyProtocolDecoder(null); + var decoder = inject(new EskyProtocolDecoder(null)); verifyAttribute(decoder, text( "ET;0;860337031066546;R;9+200717114059+41.32053+19.80761+0.30+0+0x2+8+40381744+0+1409+11"), diff --git a/src/test/java/org/traccar/protocol/ExtremTracProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ExtremTracProtocolDecoderTest.java index 29d11e02f..36a26bbe3 100644 --- a/src/test/java/org/traccar/protocol/ExtremTracProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ExtremTracProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ExtremTracProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ExtremTracProtocolDecoder(null); + var decoder = inject(new ExtremTracProtocolDecoder(null)); verifyPosition(decoder, text( "$GPRMC,862106020628733,050859.000,A,1404.8573,N,08710.9967,W,0.00,0,080117,0,,00C8,00218,99,,,,,,0.00")); diff --git a/src/test/java/org/traccar/protocol/FifotrackFrameDecoderTest.java b/src/test/java/org/traccar/protocol/FifotrackFrameDecoderTest.java index 32657b277..417c49de5 100644 --- a/src/test/java/org/traccar/protocol/FifotrackFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackFrameDecoderTest.java @@ -8,7 +8,7 @@ public class FifotrackFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FifotrackFrameDecoder(); + var decoder = inject(new FifotrackFrameDecoder()); verifyFrame( binary("24243132362c3836393436373034393239303738372c324138432c4130312c2c3139303431333135333235342c412c2d31352e3132373836382c33392e3236323530362c302c3136322c3431352c38303937323234332c302c303030302c30302c302c3634337c337c353141467c424632462c3141337c3446367c3833327c302c312c2a3534"), diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java index 6480d1dc4..ec08b432c 100644 --- a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class FifotrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FifotrackProtocolDecoder(null); + var decoder = inject(new FifotrackProtocolDecoder(null)); verifyPosition(decoder, buffer( "$$95,866104023192332,1,A03,,210414055249,460|0|25FC|104C,4.18,100,000F,0,A,2,9,22.643175,114.018150*75")); diff --git a/src/test/java/org/traccar/protocol/FlespiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlespiProtocolDecoderTest.java index 88fdb0959..c794c9094 100644 --- a/src/test/java/org/traccar/protocol/FlespiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlespiProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class FlespiProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FlespiProtocolDecoder(null); + var decoder = inject(new FlespiProtocolDecoder(null)); verifyPositions(decoder, request(HttpMethod.POST, "/", buffer("[{\"position.speed\":0,\"position.latitude\":53.90573,\"time.valid.status\":true,\"timestamp\":1506956075,\"position.satellites\":10,\"message.buffered.status\":false,\"business.mode.status\":true,\"gps.status\":true,\"position.longitude\":27.455848,\"position.direction\":0,\"ident\":\"605630\"},{\"siren.status\":false,\"business.mode.status\":true,\"position.satellites\":8,\"timestamp\":1506695785,\"led.status\":false,\"position.latitude\":53.905569,\"position.longitude\":27.455986,\"position.speed\":0,\"gradual.stop.status\":false,\"position.direction\":262.643854,\"hardware.version.enum\":223,\"vehicle.mileage\":160,\"message.buffered.status\":false,\"blinkers.status\":false,\"ident\":\"605630\",\"position.altitude\":233.48,\"immobilizer.status\":false}]"))); diff --git a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java index c819cd8bf..ffb8eb3a9 100644 --- a/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexApiProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FlexApiProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FlexApiProtocolDecoder(null); + var decoder = inject(new FlexApiProtocolDecoder(null)); verifyAttributes(decoder, text( "${\"topic\":\"v1/VF3102021113001/motion/info\",\"payload\":{\"motion.ts\":1641885877,\"motion.ax\":0.006344,\"motion.ay\":0.289384,\"motion.az\":-0.939156,\"motion.gx\":0.420000,\"motion.gy\":0.420000,\"motion.gz\":-0.280000}}xx")); diff --git a/src/test/java/org/traccar/protocol/FlexCommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexCommProtocolDecoderTest.java index 3e988ba4f..ed44fc62e 100644 --- a/src/test/java/org/traccar/protocol/FlexCommProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexCommProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FlexCommProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FlexCommProtocolDecoder(null); + var decoder = inject(new FlexCommProtocolDecoder(null)); verifyPosition(decoder, text( "7E00865067022408382201705302358271024932258006712785200700022601010224100040002C5002A2210001000000010012342107")); diff --git a/src/test/java/org/traccar/protocol/FlexibleReportProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlexibleReportProtocolDecoderTest.java index 8763887a5..6b289396d 100644 --- a/src/test/java/org/traccar/protocol/FlexibleReportProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlexibleReportProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FlexibleReportProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FlexibleReportProtocolDecoder(null); + var decoder = inject(new FlexibleReportProtocolDecoder(null)); verifyPosition(decoder, binary( "7d010015875000013001001028fd98991830002e7fffffff0c28fd989903f6540a07f250ed00000f02f2140f5ea20000000000000202d4000a1f8b0100000708ffff")); diff --git a/src/test/java/org/traccar/protocol/FlextrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FlextrackProtocolDecoderTest.java index 0c1c18a0c..6e5ebf4cf 100644 --- a/src/test/java/org/traccar/protocol/FlextrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FlextrackProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class FlextrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FlextrackProtocolDecoder(null); + var decoder = inject(new FlextrackProtocolDecoder(null)); verifyNull(decoder, text( "-1,LOGON,7000000123,8945000000")); diff --git a/src/test/java/org/traccar/protocol/FoxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FoxProtocolDecoderTest.java index 439a5553a..8e62c878e 100644 --- a/src/test/java/org/traccar/protocol/FoxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FoxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FoxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FoxProtocolDecoder(null); + var decoder = inject(new FoxProtocolDecoder(null)); verifyPosition(decoder, text( "")); diff --git a/src/test/java/org/traccar/protocol/FreedomProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FreedomProtocolDecoderTest.java index c8f7a444b..1163b4e04 100644 --- a/src/test/java/org/traccar/protocol/FreedomProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FreedomProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FreedomProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FreedomProtocolDecoder(null); + var decoder = inject(new FreedomProtocolDecoder(null)); verifyPosition(decoder, text( "IMEI,353358011714362,2014/05/22, 20:49:32, N, Lat:4725.9624, E, Lon:01912.5483, Spd:5.05"), diff --git a/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java index 6a7a15397..a7ce042e5 100644 --- a/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FreematicsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FreematicsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FreematicsProtocolDecoder(null); + var decoder = inject(new FreematicsProtocolDecoder(null)); verifyPositions(decoder, text( "M0ZR4X0#0:204391,11:140221,10:8445000,A:49.215920,B:18.737755,C:410,D:0,E:208,24:1252,20:0;0;0,82:47*B5")); diff --git a/src/test/java/org/traccar/protocol/FutureWayFrameDecoderTest.java b/src/test/java/org/traccar/protocol/FutureWayFrameDecoderTest.java index b8eb3908e..a101ef45d 100644 --- a/src/test/java/org/traccar/protocol/FutureWayFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FutureWayFrameDecoderTest.java @@ -8,7 +8,7 @@ public class FutureWayFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FutureWayFrameDecoder(); + var decoder = inject(new FutureWayFrameDecoder()); verifyFrame( binary("343130303030303039424130303030344750533a562c3230303930323039333333332c302e3030303030304e2c302e303030303030452c302e3030302c302e3030300d0a574946493a332c317c39302d36372d31432d46372d32312d36437c353226327c38302d38392d31372d43362d37392d41307c353426337c34302d46342d32302d45462d44442d32417c35380d0a4c42533a3436302c302c34363437353036362c36390d0a36413432"), diff --git a/src/test/java/org/traccar/protocol/FutureWayProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FutureWayProtocolDecoderTest.java index fbb0a2aba..e529d5c90 100644 --- a/src/test/java/org/traccar/protocol/FutureWayProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FutureWayProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class FutureWayProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new FutureWayProtocolDecoder(null); + var decoder = inject(new FutureWayProtocolDecoder(null)); verifyNull(decoder, text( "410000003F2000020,IMEI:354828100126461,battery level:6,network type:7,CSQ:236F42")); diff --git a/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java index 0d3199eab..a5aba3513 100644 --- a/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoFrameDecoderTest.java @@ -10,7 +10,7 @@ public class GalileoFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GalileoFrameDecoder(); + var decoder = inject(new GalileoFrameDecoder()); assertEquals( binary("011780011102e603383633353931303238393630323437043200801c"), diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java index 66b375b8a..d76fc5895 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GalileoProtocolDecoder(null); + var decoder = inject(new GalileoProtocolDecoder(null)); verifyPositions(decoder, binary( "011801018202130338363833343530333230343234323604640010a406207caa9f5b300c830a7901ca0ec802330000000034b802350540003e41703f422b1043234504004600e09000000000a000a100a200a300a400a500a600a700a800a900aa00ab00ac00ad00ae00af00b00000b10000b20000b30000b40000b50000b60000b70000b80000b90000c000000000c100000000c200000000c300000000c400c500c600c700c800c900ca00cb00cc00cd00ce00cf00d000d100d200d4d3140000d60000d70000d80000d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000f400000000f500000000f600000000f700000000f800000000f9000000008960")); diff --git a/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java index 24686e220..bfb33de22 100644 --- a/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java @@ -17,7 +17,7 @@ public class GatorProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GatorProtocolDecoder(null); + var decoder = inject(new GatorProtocolDecoder(null)); verifyAttributes(decoder, binary( "242480002600341cad190917022021812497260280594200000000c047010000135400009bb600ff00b90d")); diff --git a/src/test/java/org/traccar/protocol/GenxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GenxProtocolDecoderTest.java index 382c974ce..67a730f97 100644 --- a/src/test/java/org/traccar/protocol/GenxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GenxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GenxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GenxProtocolDecoder(null); + var decoder = inject(new GenxProtocolDecoder(null)); decoder.setReportColumns("28,2,3,4,13,17,10,23,27,11,7,8,46,56,59,70,74,75,77,89,90,93,99,107,112,113,114,176,175,178,181,182"); diff --git a/src/test/java/org/traccar/protocol/Gl100ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl100ProtocolDecoderTest.java index 50f993839..31ae1d5e8 100644 --- a/src/test/java/org/traccar/protocol/Gl100ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl100ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Gl100ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gl100ProtocolDecoder(null); + var decoder = inject(new Gl100ProtocolDecoder(null)); verifyPosition(decoder, text( "+RESP:GTLGL,359464030492644,1,2,1,0,0.4,0,299.7,1,5.455551,51.449776,20160311083229,0204,0016,03EC,BD94,00,0036,0102090501")); diff --git a/src/test/java/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java index b8ce8af5d..cad70c35b 100644 --- a/src/test/java/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Gl200BinaryProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gl200BinaryProtocolDecoder(null); + var decoder = inject(new Gl200BinaryProtocolDecoder(null)); verifyPosition(decoder, binary( "2b4556542d00fc1fbf0063450102020956325403000343056437f8220700000200000000010000160100f2007eff75a1f0025c6b1a07e1080108241a02680003189c1ac500000000000002100800000000000000000007e1080108241a19e24e4e0d0a")); diff --git a/src/test/java/org/traccar/protocol/Gl200FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200FrameDecoderTest.java index 17eed8a59..51816222d 100644 --- a/src/test/java/org/traccar/protocol/Gl200FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200FrameDecoderTest.java @@ -10,7 +10,7 @@ public class Gl200FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gl200FrameDecoder(); + var decoder = inject(new Gl200FrameDecoder()); assertEquals( binary("2b4c474e00ff0026fe110b07020106563454040d054905000007e4031911213905083abd0d0a"), diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 429ee15c7..6857feddc 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gl200TextProtocolDecoder(null); + var decoder = inject(new Gl200TextProtocolDecoder(null)); verifyPosition(decoder, buffer( "+RESP:GTFRI,5E0100,861971050039361,,,,10,1,1,10.4,140,196.9,-80.709946,35.016525,20220302220944,0310,0260,1CE9,52A1,00,0.0,,,,,420000,,,,20220302220948,1B0B$")); diff --git a/src/test/java/org/traccar/protocol/GlobalSatProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GlobalSatProtocolDecoderTest.java index 3f5296f4b..e244a835d 100644 --- a/src/test/java/org/traccar/protocol/GlobalSatProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GlobalSatProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GlobalSatProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GlobalSatProtocolDecoder(null); + var decoder = inject(new GlobalSatProtocolDecoder(null)); verifyNull(decoder, text( "GSh,131826789036289,3,M,ea04*3d")); diff --git a/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java index 1dd5c2542..f0ba813ca 100644 --- a/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class GlobalstarProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GlobalstarProtocolDecoder(null); + var decoder = inject(new GlobalstarProtocolDecoder(null)); verifyNull(decoder, request(HttpMethod.POST, "/", buffer( "\n", diff --git a/src/test/java/org/traccar/protocol/GnxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GnxProtocolDecoderTest.java index 8bd5e2bd5..592c2de91 100644 --- a/src/test/java/org/traccar/protocol/GnxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GnxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GnxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GnxProtocolDecoder(null); + var decoder = inject(new GnxProtocolDecoder(null)); verifyPosition(decoder, text( "$GNX_MIF,865733022354161,143,0,172642,180316,172642,180316,1,13.034581,N,080.234521,E,0,05396274,ROUTE_2#########,Deo ############,GNX04008,B0*")); diff --git a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java index bb79f4f25..71ffbb587 100644 --- a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class GoSafeProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GoSafeProtocolDecoder(null); + var decoder = inject(new GoSafeProtocolDecoder(null)); verifyPositions(decoder, false, text( "*GS06,357330050846344,RST#")); diff --git a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java index 373858c79..a6e3f2d69 100644 --- a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class GotopProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GotopProtocolDecoder(null); + var decoder = inject(new GotopProtocolDecoder(null)); verifyNull(decoder, text( "")); diff --git a/src/test/java/org/traccar/protocol/Gps056FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Gps056FrameDecoderTest.java index f6524f82b..cb75b4035 100644 --- a/src/test/java/org/traccar/protocol/Gps056FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps056FrameDecoderTest.java @@ -10,7 +10,7 @@ public class Gps056FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gps056FrameDecoder(); + var decoder = inject(new Gps056FrameDecoder()); assertEquals( binary("242435314750534c5f30323836323436323033333738323934361905110f160b0b7710584e1cbd1b9b4500005b100300fb0a071700ffff23"), diff --git a/src/test/java/org/traccar/protocol/Gps056ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gps056ProtocolDecoderTest.java index 01fa98ba4..ac3738644 100644 --- a/src/test/java/org/traccar/protocol/Gps056ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps056ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Gps056ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gps056ProtocolDecoder(null); + var decoder = inject(new Gps056ProtocolDecoder(null)); verifyNull(decoder, buffer( "$$25LOGN_118624620337829462.1#")); diff --git a/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java index 79dc8ab7b..425fcd8ae 100644 --- a/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Gps103ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gps103ProtocolDecoder(null); + var decoder = inject(new Gps103ProtocolDecoder(null)); verifyPosition(decoder, text( "imei:864035050002451,tracker,201223064947,,F,064947,A,1935.70640,N,09859.94436,W,0.025,;")); diff --git a/src/test/java/org/traccar/protocol/GpsGateProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GpsGateProtocolDecoderTest.java index c935fb3c2..a1f81b329 100644 --- a/src/test/java/org/traccar/protocol/GpsGateProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GpsGateProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GpsGateProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GpsGateProtocolDecoder(null); + var decoder = inject(new GpsGateProtocolDecoder(null)); verifyPosition(decoder, text( "$FRCMD,0097,_SendMessage,,7618.51990,S,4002.26182,E,350.0,1.08,0.0,250816,183522.000,0*7F")); diff --git a/src/test/java/org/traccar/protocol/GpsMarkerProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GpsMarkerProtocolDecoderTest.java index c0b4966a8..bc7910779 100644 --- a/src/test/java/org/traccar/protocol/GpsMarkerProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GpsMarkerProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class GpsMarkerProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GpsMarkerProtocolDecoder(null); + var decoder = inject(new GpsMarkerProtocolDecoder(null)); verifyPosition(decoder, text( "$GM23D863071014445404T260816142611N55441051E037325071033063C0530304#")); diff --git a/src/test/java/org/traccar/protocol/GpsmtaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GpsmtaProtocolDecoderTest.java index 7170718f6..d1326515f 100644 --- a/src/test/java/org/traccar/protocol/GpsmtaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GpsmtaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GpsmtaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GpsmtaProtocolDecoder(null); + var decoder = inject(new GpsmtaProtocolDecoder(null)); verifyPosition(decoder, text( "3085a94ef459 1446536867 49.81621 24.054207 1 0 22 0 10 12 24 0 0")); diff --git a/src/test/java/org/traccar/protocol/GranitFrameDecoderTest.java b/src/test/java/org/traccar/protocol/GranitFrameDecoderTest.java index b4e24f961..a61e708f7 100644 --- a/src/test/java/org/traccar/protocol/GranitFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GranitFrameDecoderTest.java @@ -10,7 +10,7 @@ public class GranitFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GranitFrameDecoder(); + var decoder = inject(new GranitFrameDecoder()); assertEquals( binary("2b525243427e1a003e2934757c57b8b03c38d279b4e61e9bd7006b000000001c00002a4533"), diff --git a/src/test/java/org/traccar/protocol/GranitProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GranitProtocolDecoderTest.java index 7fd5ffe0e..d2e181e09 100644 --- a/src/test/java/org/traccar/protocol/GranitProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GranitProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class GranitProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new GranitProtocolDecoder(null); + var decoder = inject(new GranitProtocolDecoder(null)); verifyPositions(decoder, binary( "2b444441547e8400c500040130050c43495808002839aee3150200000000640000000000000008002839aee3150200000000640000000000000008002839aee3150200000000640000000000000008002839aee3150200000000640000000000000008002839aee3150200000000640000000000000008002839aee3150200000000640000000000000014002a37420d0a")); diff --git a/src/test/java/org/traccar/protocol/Gs100ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gs100ProtocolDecoderTest.java index 68c9b8219..ce2768448 100644 --- a/src/test/java/org/traccar/protocol/Gs100ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gs100ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Gs100ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gs100ProtocolDecoder(null); + var decoder = inject(new Gs100ProtocolDecoder(null)); verifyNull(decoder, binary( "474C490F383632343632303332353036373030133839333831303131363039313838343837323546084657312E302E3236")); diff --git a/src/test/java/org/traccar/protocol/Gt02ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt02ProtocolDecoderTest.java index 9d36ef346..25f59a948 100644 --- a/src/test/java/org/traccar/protocol/Gt02ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt02ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Gt02ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gt02ProtocolDecoder(null); + var decoder = inject(new Gt02ProtocolDecoder(null)); verifyAttributes(decoder, binary( "6868150000035889905895258400831c07415045584f4b210d0a")); diff --git a/src/test/java/org/traccar/protocol/Gt06FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06FrameDecoderTest.java index 059674398..a9d011277 100644 --- a/src/test/java/org/traccar/protocol/Gt06FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Gt06FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gt06FrameDecoder(); + var decoder = inject(new Gt06FrameDecoder()); verifyFrame( binary("787803691604130318491475905BD30E25001E10BBF7635D14759006E626560501CC0028660F213228660F1F2828660EA81E286610731428660F20140D0A"), diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index b65b6709e..5b355e4f5 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gt06ProtocolDecoder(null); + var decoder = inject(new Gt06ProtocolDecoder(null)); verifyNull(decoder, binary( "787805120099abec0d0a")); diff --git a/src/test/java/org/traccar/protocol/Gt30ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt30ProtocolDecoderTest.java index 24addc8b4..48c4306d6 100644 --- a/src/test/java/org/traccar/protocol/Gt30ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt30ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Gt30ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Gt30ProtocolDecoder(null); + var decoder = inject(new Gt30ProtocolDecoder(null)); verifyPosition(decoder, text( "$$005D3037811014 9955102834.000,A,3802.8629,N,02349.7163,E,0.00,,060117,,*13|1.3|26225BD")); diff --git a/src/test/java/org/traccar/protocol/H02FrameDecoderTest.java b/src/test/java/org/traccar/protocol/H02FrameDecoderTest.java index 2294b773b..c61c0f0c9 100644 --- a/src/test/java/org/traccar/protocol/H02FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/H02FrameDecoderTest.java @@ -10,7 +10,7 @@ public class H02FrameDecoderTest extends ProtocolTest { @Test public void testDecodeShort() throws Exception { - var decoder = new H02FrameDecoder(0); + var decoder = inject(new H02FrameDecoder(0)); assertEquals( binary("2a48512c3335353438383032303131333931312c56312c3031323934352c412c353233312e37393238332c4e2c30313332342e31303731382c452c302e30352c302c3137303231372c464646464646464623"), @@ -37,7 +37,7 @@ public class H02FrameDecoderTest extends ProtocolTest { @Test public void testDecodeLong() throws Exception { - var decoder = new H02FrameDecoder(0); + var decoder = inject(new H02FrameDecoder(0)); assertEquals( binary("24410600082621532131081504419390060740418306000000fffffbfdff0015060000002c02dc0c000000001f"), @@ -48,7 +48,7 @@ public class H02FrameDecoderTest extends ProtocolTest { @Test public void testDecodeAlternative() throws Exception { - var decoder = new H02FrameDecoder(0); + var decoder = inject(new H02FrameDecoder(0)); assertEquals( binary("2a48512c343230363131393133302c4e42522c3130323430332c3233382c312c302c372c313131312c323236342c36332c313131312c323236352c35382c313131312c323236362c35302c313131312c333133352c33372c313131312c3630352c33332c313131312c343932302c33302c313131312c3630372c32382c3131303131372c46464646444646462c3623"), diff --git a/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java index ad5f82176..278931466 100644 --- a/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class H02ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new H02ProtocolDecoder(null); + var decoder = inject(new H02ProtocolDecoder(null)); verifyPosition(decoder, buffer( "*HQ,5905101893,V1,105759,A,37573392,S,145037022,E,000.00,173,280122,FF7FFBFF,,,9059e2c,8232,4#")); @@ -270,7 +270,7 @@ public class H02ProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeStatus() throws Exception { - var decoder = new H02ProtocolDecoder(null); + var decoder = inject(new H02ProtocolDecoder(null)); verifyAttribute(decoder, buffer( "*HQ,2705171109,V1,213324,A,5002.5849,N,01433.7822,E,0.00,000,140613,FFFFFFFF#"), diff --git a/src/test/java/org/traccar/protocol/HaicomProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HaicomProtocolDecoderTest.java index 9d80940ea..9d26d56c3 100644 --- a/src/test/java/org/traccar/protocol/HaicomProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HaicomProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class HaicomProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HaicomProtocolDecoder(null); + var decoder = inject(new HaicomProtocolDecoder(null)); verifyPosition(decoder, text( "$GPRS012497007097169,T100001,150618,230031,5402267400332464,0004,2014,000001,,,1,00#V040*"), diff --git a/src/test/java/org/traccar/protocol/HomtecsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HomtecsProtocolDecoderTest.java index 192aa3010..8fe4d2c8b 100644 --- a/src/test/java/org/traccar/protocol/HomtecsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HomtecsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class HomtecsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HomtecsProtocolDecoder(null); + var decoder = inject(new HomtecsProtocolDecoder(null)); verifyNull(decoder, text( "MDS0001_R6d1821f7,170323,143601.00,04,,,,,,,,,")); diff --git a/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java index 3ee0a5e01..ed7b0534b 100644 --- a/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HoopoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class HoopoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HoopoProtocolDecoder(null); + var decoder = inject(new HoopoProtocolDecoder(null)); verifyPosition(decoder, text( "{ \"deviceId\": \"BCCD0654\", \"assetName\": \"BCCD0654\", \"assetType\": \"???? ?????? - ??? 8\", \"eventData\": { \"latitude\": 31.97498, \"longitude\": 34.80802, \"locationName\": \"\", \"accuracyLevel\": \"High\", \"eventType\": \"Arrival\", \"batteryLevel\": 100, \"receiveTime\": \"2021-09-20T18:52:32Z\" }, \"eventTime\": \"2021-09-20T08:52:02Z\", \"serverReportTime\": \"0001-01-01T00:00:00Z\" }")); diff --git a/src/test/java/org/traccar/protocol/HuaShengFrameDecoderTest.java b/src/test/java/org/traccar/protocol/HuaShengFrameDecoderTest.java index 228f41ee8..991e0b36d 100644 --- a/src/test/java/org/traccar/protocol/HuaShengFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuaShengFrameDecoderTest.java @@ -10,7 +10,7 @@ public class HuaShengFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HuaShengFrameDecoder(); + var decoder = inject(new HuaShengFrameDecoder()); assertEquals( binary("c0010c00120060000000000004000600010100c0"), diff --git a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java index 74671b845..7002d7e88 100644 --- a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class HuaShengProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HuaShengProtocolDecoder(null); + var decoder = inject(new HuaShengProtocolDecoder(null)); verifyNull(decoder, binary( "c00000007eaa000000000000cb8000000032313130313030393238323800e9abafffd615d2000000000008000000010015ffffff0000000000000004e7ffffffffff0005000a10080001d5ab000900154b4e4142323531324d4b54353638363630000f00133335343434343131353130333138380014000b00000000000000c0")); diff --git a/src/test/java/org/traccar/protocol/HuabaoFrameDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoFrameDecoderTest.java index d4789032d..6b902fb46 100644 --- a/src/test/java/org/traccar/protocol/HuabaoFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoFrameDecoderTest.java @@ -8,7 +8,7 @@ public class HuabaoFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HuabaoFrameDecoder(); + var decoder = inject(new HuabaoFrameDecoder()); verifyFrame( binary("283734303139303331313138352c312c3030312c454c4f434b2c332c35323934333929"), diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index c45effbc5..0b36b8f4d 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HuabaoProtocolDecoder(null); + var decoder = inject(new HuabaoProtocolDecoder(null)); verifyNull(decoder, buffer( "(794104004140,1,001,BASE,2,TIME)")); diff --git a/src/test/java/org/traccar/protocol/HunterProProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HunterProProtocolDecoderTest.java index 81fdae95c..5503ab02c 100644 --- a/src/test/java/org/traccar/protocol/HunterProProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HunterProProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class HunterProProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new HunterProProtocolDecoder(null); + var decoder = inject(new HunterProProtocolDecoder(null)); verifyPosition(decoder, text( ">0002<$GPRMC,170559.000,A,0328.3045,N,07630.0735,W,0.73,266.16,200816,,,A77, s000078015180\",0MD")); diff --git a/src/test/java/org/traccar/protocol/IdplProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/IdplProtocolDecoderTest.java index a5141c389..1bd52ce89 100644 --- a/src/test/java/org/traccar/protocol/IdplProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/IdplProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class IdplProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new IdplProtocolDecoder(null); + var decoder = inject(new IdplProtocolDecoder(null)); verifyPosition(decoder, text( "*ID1,863071011086474,210314,153218,A,1831.4577,N,07351.1433,E,0.79,240.64,9,20,A,1,4.20,0,1,01,1,0,0,A01,R,935D#"), diff --git a/src/test/java/org/traccar/protocol/IntellitracProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/IntellitracProtocolDecoderTest.java index ee3a25cbe..b6e12aef5 100644 --- a/src/test/java/org/traccar/protocol/IntellitracProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/IntellitracProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class IntellitracProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new IntellitracProtocolDecoder(null); + var decoder = inject(new IntellitracProtocolDecoder(null)); verifyPosition(decoder, text( "359316075744331,20201008181424,12.014662,57.826301,0,76,24,10,997,3,0,0.000,4.208,20201008181424,0")); diff --git a/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java index ca72874ef..c668084a1 100644 --- a/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class IotmProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new IotmProtocolDecoder(null); + var decoder = inject(new IotmProtocolDecoder(null)); verifyNull(decoder, MqttMessageBuilders.connect().clientId( "123456789012345").build()); diff --git a/src/test/java/org/traccar/protocol/ItsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/ItsFrameDecoderTest.java index 363185b4c..26f28916c 100644 --- a/src/test/java/org/traccar/protocol/ItsFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ItsFrameDecoderTest.java @@ -8,7 +8,7 @@ public class ItsFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ItsFrameDecoder(); + var decoder = inject(new ItsFrameDecoder()); verifyFrame( binary("242c2c3836383732383033373731373434312c312e3444335f4149533134305f312e302c56455253494f4e312e302c32382e3633333731372c4e2c37372e3232323730322c45"), diff --git a/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java index dfd86969a..dd8d3a0d9 100644 --- a/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class ItsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ItsProtocolDecoder(null); + var decoder = inject(new ItsProtocolDecoder(null)); verifyNull(decoder, text( "$,LGN,MARK,000000000,358980100077446,V0.0.1,AIS140,19.804487,N,75.225876,E,*")); diff --git a/src/test/java/org/traccar/protocol/Ivt401ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Ivt401ProtocolDecoderTest.java index 8a71cb4d5..b08dff4e7 100644 --- a/src/test/java/org/traccar/protocol/Ivt401ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Ivt401ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Ivt401ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Ivt401ProtocolDecoder(null); + var decoder = inject(new Ivt401ProtocolDecoder(null)); verifyPosition(decoder, text( "(TLA,356917051007891,190118,090211,+16.986606,+82.242416,0,66,4,13,1,5,000,00,0.0,11.59,8.30,37.77,0.0,1,1.02,0,0,208,0,0,0,0,000000000,0,0,0,0,0,0,0,1,8654604,5,9,114)")); diff --git a/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java index 9e01d7d68..b275e6d01 100644 --- a/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/JidoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class JidoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new JidoProtocolDecoder(null); + var decoder = inject(new JidoProtocolDecoder(null)); verifyPosition(decoder, text( "*12345678910101000,01,A,130517,160435,1820.5845,N,07833.2478,E,20,0,067,045,05,28,26,1,075,Y,1,0000,0000,0000,59")); diff --git a/src/test/java/org/traccar/protocol/JpKorjarProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/JpKorjarProtocolDecoderTest.java index 13137006c..a1b0acac5 100644 --- a/src/test/java/org/traccar/protocol/JpKorjarProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/JpKorjarProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class JpKorjarProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new JpKorjarProtocolDecoder(null); + var decoder = inject(new JpKorjarProtocolDecoder(null)); verifyPosition(decoder, text( "KORJAR.PL,329587014519383,160910144240,52.247254N,021.013375E,0.00,1,F:4.18V,1 260 01 794B 3517,")); diff --git a/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java b/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java index 42777e419..1bc5d8480 100644 --- a/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/JsonFrameDecoderTest.java @@ -8,7 +8,7 @@ public class JsonFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new JsonFrameDecoder(); + var decoder = inject(new JsonFrameDecoder()); verifyFrame( binary("7b226465764964223a2243485a4430384b504430323130343235303436222c2264657654797065223a322c226861726456657273696f6e223a224844545456413139222c226d736754797065223a3131302c2270726f746f636f6c56657273696f6e223a225631222c22736f667456657273696f6e223a22332e312e38222c22737769746368436162537461747573223a2231222c2274786e4e6f223a2231363235323132373431353337227d"), diff --git a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java index eda97ba2d..8e408e50f 100644 --- a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Jt600FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Jt600FrameDecoder(); + var decoder = inject(new Jt600FrameDecoder()); verifyFrame( binary("2480413009781914003406102107544354193631006213423b00000000006c070000000020e064f91ea0671d00020f0f0f0f0f0f0f0f0f0f07f100ea0f6e"), diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 3bf01c1ae..c8db31ad0 100644 --- a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Jt600ProtocolDecoder(null); + var decoder = inject(new Jt600ProtocolDecoder(null)); verifyPosition(decoder, buffer( "(8000632862,P45,290322,132412,25.28217,S,57.54683,W,A,0,0,5,0,0000000000,0,0,9,0)")); diff --git a/src/test/java/org/traccar/protocol/KenjiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/KenjiProtocolDecoderTest.java index 53ef1d5ca..a705d8082 100755 --- a/src/test/java/org/traccar/protocol/KenjiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/KenjiProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class KenjiProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new KenjiProtocolDecoder(null); + var decoder = inject(new KenjiProtocolDecoder(null)); verifyPosition(decoder, text( ">C800000,M005004,O0000,I0002,D124057,A,S3137.2783,W05830.2978,T000.0,H254.3,Y240116,G06*17"), diff --git a/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java index 5c2b0732b..155493bea 100644 --- a/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/KhdProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class KhdProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new KhdProtocolDecoder(null); + var decoder = inject(new KhdProtocolDecoder(null)); verifyPosition(decoder, binary( "2929800028258b8c10210731035840031534240542120200000337fb000000ffff5a00000a0000000005005d0d")); diff --git a/src/test/java/org/traccar/protocol/L100FrameDecoderTest.java b/src/test/java/org/traccar/protocol/L100FrameDecoderTest.java index 45c69105b..084ae0498 100644 --- a/src/test/java/org/traccar/protocol/L100FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/L100FrameDecoderTest.java @@ -8,7 +8,7 @@ public class L100FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new L100FrameDecoder(); + var decoder = inject(new L100FrameDecoder()); verifyFrame( binary("41544c2c4c2c3836383334353033383137313936332c4e2c3230313231382c3039333031362c412c3032352e3036373134342c4e2c3035352e3134343833332c452c3030302e302c4750532c333933392c3432342c30332c30303430352c303038383334"), diff --git a/src/test/java/org/traccar/protocol/L100ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/L100ProtocolDecoderTest.java index d4bef3885..56281cda0 100644 --- a/src/test/java/org/traccar/protocol/L100ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/L100ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class L100ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new L100ProtocolDecoder(null); + var decoder = inject(new L100ProtocolDecoder(null)); verifyPosition(decoder, text( "ATL,NP,868004029750174,$GPRMC,062943,A,2533.6719,N,09154.3203,E,0,179,311218,,,*39,#01111011000000,0,0,0,934.82,27.13,4.0,25,405,755,15af,974b,0,0,0,ATL")); diff --git a/src/test/java/org/traccar/protocol/LacakProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LacakProtocolDecoderTest.java index c407d1e64..45544241f 100644 --- a/src/test/java/org/traccar/protocol/LacakProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/LacakProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class LacakProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new LacakProtocolDecoder(null); + var decoder = inject(new LacakProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{\"location\":{\"event\":\"motionchange\",\"is_moving\":false,\"uuid\":\"0e9a2473-a9a7-4c00-997b-fb97d2154e75\",\"timestamp\":\"2021-07-21T08:06:34.444Z\",\"odometer\":0,\"coords\":{\"latitude\":-6.1148096,\"longitude\":106.6837015,\"accuracy\":3.8,\"speed\":18.67,\"speed_accuracy\":0.26,\"heading\":63,\"heading_accuracy\":0.28,\"altitude\":35.7,\"altitude_accuracy\":3.8},\"activity\":{\"type\":\"still\",\"confidence\":100},\"battery\":{\"is_charging\":false,\"level\":0.79},\"extras\":{}},\"device_id\":\"8737767034\"}"))); diff --git a/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java index 1d5819603..aacf9abc8 100644 --- a/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class LaipacProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new LaipacProtocolDecoder(null); + var decoder = inject(new LaipacProtocolDecoder(null)); verifyPosition(decoder, text( "$AVRMC,80006405,212645,r,3013.9938,N,08133.3998,W,0.00,0.00,010317,a,4076,0,1,0,0,53170583,310260*78")); diff --git a/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java index aed82eb41..ea31bc99d 100644 --- a/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class LeafSpyProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new LeafSpyProtocolDecoder(null); + var decoder = inject(new LeafSpyProtocolDecoder(null)); verifyNull(decoder, request( "/?Lat=60.0&Long=30.0")); diff --git a/src/test/java/org/traccar/protocol/M2cProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/M2cProtocolDecoderTest.java index ede056f96..674738c82 100644 --- a/src/test/java/org/traccar/protocol/M2cProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/M2cProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class M2cProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new M2cProtocolDecoder(null); + var decoder = inject(new M2cProtocolDecoder(null)); verifyPositions(decoder, text( "[#M2C,2020,P1.B1.H3.F9.R1,102,864547034433966,1,L,0,20,171221,062016,28.647552,77.192841,0,0,0.0,0,0,64,255,11983,0,0,0,0.0,0,0,0,404,4,1F6,4D77,31,0*7524\r\n", diff --git a/src/test/java/org/traccar/protocol/M2mProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/M2mProtocolDecoderTest.java index f318dcfef..0d812ebfc 100644 --- a/src/test/java/org/traccar/protocol/M2mProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/M2mProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class M2mProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new M2mProtocolDecoder(null); + var decoder = inject(new M2mProtocolDecoder(null)); verifyNull(decoder, binary( "235A3C2A2624215C287D70212A21254C7C6421220B0B0B")); diff --git a/src/test/java/org/traccar/protocol/MaestroProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MaestroProtocolDecoderTest.java index 19f9b9da7..be0fe502e 100644 --- a/src/test/java/org/traccar/protocol/MaestroProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MaestroProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class MaestroProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MaestroProtocolDecoder(null); + var decoder = inject(new MaestroProtocolDecoder(null)); verifyPosition(decoder, text( "@353893040202807,705,UPV-02,1,13.2,17,0,0,16/09/11,11:42:49,0.352705,32.647918,1210.5,0.000000,35.33,11,0.8,0.000,0!\0")); diff --git a/src/test/java/org/traccar/protocol/ManPowerProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ManPowerProtocolDecoderTest.java index 74f3ff1ec..a77043b9d 100644 --- a/src/test/java/org/traccar/protocol/ManPowerProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ManPowerProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ManPowerProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ManPowerProtocolDecoder(null); + var decoder = inject(new ManPowerProtocolDecoder(null)); verifyPosition(decoder, text( "simei:352581250259539,,,tracker,51,24,1.73,130426023608,A,3201.5462,N,03452.2975,E,0.01,28B9,1DED,425,01,1x0x0*0x1*60x+2,en-us,"), diff --git a/src/test/java/org/traccar/protocol/Mavlink2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Mavlink2ProtocolDecoderTest.java index ccddb6a11..0c74d4772 100644 --- a/src/test/java/org/traccar/protocol/Mavlink2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Mavlink2ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Mavlink2ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Mavlink2ProtocolDecoder(null); + var decoder = inject(new Mavlink2ProtocolDecoder(null)); verifyAttributes(decoder, binary( "fd1c0000ce01012100004da91f004005d323b89aa30ea6ed070099fb0100f7fffdff0000942c4a88")); diff --git a/src/test/java/org/traccar/protocol/MegastekFrameDecoderTest.java b/src/test/java/org/traccar/protocol/MegastekFrameDecoderTest.java index 19e5cb0ab..854564cd2 100644 --- a/src/test/java/org/traccar/protocol/MegastekFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MegastekFrameDecoderTest.java @@ -8,7 +8,7 @@ public class MegastekFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MegastekFrameDecoder(); + var decoder = inject(new MegastekFrameDecoder()); verifyFrame( binary("30313337244d47563030322c3335343535303035303239323636392c4756543930302c522c3134313231352c3033313830342c412c2c532c2c452c30302c30332c30302c332e36372c302e3030302c302e30302c3131372e312c302e302c3531302c31302c2c2c2c303030302c303030302c32322c31322c302c202c202c2c312d312c39382c5057204f4e3b21"), diff --git a/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java index 83d62e766..ea55a8b1c 100644 --- a/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MegastekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MegastekProtocolDecoder(null); + var decoder = inject(new MegastekProtocolDecoder(null)); verifyPosition(decoder, text( "$MGV002,860719020193193,,S,070521,160748,V,2255.09165,N,11404.01322,E,00,00,00,,,,,,,,,,,,,,,,,,,10,015,Restart;!")); diff --git a/src/test/java/org/traccar/protocol/MeiligaoFrameDecoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoFrameDecoderTest.java index c0e5f1e97..379cf28f9 100644 --- a/src/test/java/org/traccar/protocol/MeiligaoFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeiligaoFrameDecoderTest.java @@ -11,7 +11,7 @@ public class MeiligaoFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MeiligaoFrameDecoder(); + var decoder = inject(new MeiligaoFrameDecoder()); assertNull( decoder.decode(null, null, binary("00"))); diff --git a/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java index 087701be4..4c6eae847 100644 --- a/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MeiligaoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MeiligaoProtocolDecoder(null); + var decoder = inject(new MeiligaoProtocolDecoder(null)); verifyAttribute(decoder, binary( "2424008f142180340967ff99553033333233302e3030302c412c313531362e383039392c4e2c31303435322e383835352c452c302e30302c33332c3038313232302c2c2a33367c302e387c3132337c323130307c303030302c303030302c303230452c303241417c30323038303030353038394530304531434638347c31437c31373243353832437c3042a8060d0a"), diff --git a/src/test/java/org/traccar/protocol/MeitrackFrameDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackFrameDecoderTest.java index 38d0f2f92..a55935ed2 100644 --- a/src/test/java/org/traccar/protocol/MeitrackFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackFrameDecoderTest.java @@ -10,7 +10,7 @@ public class MeitrackFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MeitrackFrameDecoder(); + var decoder = inject(new MeitrackFrameDecoder()); assertEquals( binary("24244e3132372c3836333037313031333830333036362c4141412c33352c2d312e3330323638302c33362e3835323133352c3135303430393231313032362c412c392c302c302e312c302c352c313635332c343039362c33323634382c3633397c30327c313030347c3930432c303030302c307c307c307c3346467c3330302c2a37430d0a"), diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 1c90468bd..d4ecae10a 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MeitrackProtocolDecoder(null); + var decoder = inject(new MeitrackProtocolDecoder(null)); verifyPositions(decoder, binary( "2424423233392c3836323039303035303030373436352c4343452c0100000003004300130006050006000700140015801b00080800000900000a00000b0000165105198d011a630540160005024c5e910103590bfe0204922153290c6b2501000dd5b50200004300130006050006000700140015011b00080800000900000a00000b0000165005198d011a630540010005024c5e910103590bfe0204932153290c6b2501000dd6b50200004300130006050006000700140015011b00080800000900000a00000b0000165205198d011a630540230005024c5e910103590bfe0204942153290c6b2501000dd7b50200002a43330d0a")); diff --git a/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java index ca8b67a46..5e36abe5b 100644 --- a/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MictrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeStandard() throws Exception { - var decoder = new MictrackProtocolDecoder(null); + var decoder = inject(new MictrackProtocolDecoder(null)); verifyAttributes(decoder, text( "MT;5;867035041396795;Y1;220111085741+test,8c:53:c3:db:e7:26,-58,jiuide-842,80:26:89:f0:5e:4f,-74,jiu2ide 403,94:e4:4b:0a:31:08,-75,jiu3ide,7a:91:e9:50:26:0b,-85,CNet-9rNe,78:91:e9:40:26:0b,-87+0+4092+1")); @@ -48,7 +48,7 @@ public class MictrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeLowAltitude() throws Exception { - var decoder = new MictrackProtocolDecoder(null); + var decoder = inject(new MictrackProtocolDecoder(null)); verifyPositions(decoder, text( "861836051888035$162835.00,A,4139.6460,N,07009.7239,W,,41.53,-25.8,220621")); diff --git a/src/test/java/org/traccar/protocol/MilesmateProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MilesmateProtocolDecoderTest.java index 69fd82886..275672554 100644 --- a/src/test/java/org/traccar/protocol/MilesmateProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MilesmateProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class MilesmateProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MilesmateProtocolDecoder(null); + var decoder = inject(new MilesmateProtocolDecoder(null)); verifyPosition(decoder, text( "ApiString={A:861359037373030,B:09.8,C:00.0,D:083506,E:2838.5529N,F:07717.8049E,G:000.00,H:170918,I:G,J:00004100,K:0000000A,L:1234,M:126.86}")); diff --git a/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java index 1a9756226..a8f1be855 100644 --- a/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MiniFinderProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MiniFinderProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MiniFinderProtocolDecoder(null); + var decoder = inject(new MiniFinderProtocolDecoder(null)); verifyNull(decoder, text( "!1,867273023933661,V07S.5701.1621,100")); diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index 1813a5370..a6006d6a7 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Minifinder2ProtocolDecoder(null); + var decoder = inject(new Minifinder2ProtocolDecoder(null)); verifyPositions(decoder, binary( "AB103D0035A700000110013836373733303035333430333237390924AC5783620103C250162030CC5F0D5002FB432D00AF005A3158006D0A00000B0931EC5783620A000000")); diff --git a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java index ddfa6ad8b..fea74db7a 100644 --- a/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MobilogixProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MobilogixProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MobilogixProtocolDecoder(null); + var decoder = inject(new MobilogixProtocolDecoder(null)); verifyAttributes(decoder, text( "[2021-08-20 19:27:14,T14,1,V1.3.5,201909000982,53,12.18")); diff --git a/src/test/java/org/traccar/protocol/MoovboxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MoovboxProtocolDecoderTest.java index af19b8222..82781550e 100644 --- a/src/test/java/org/traccar/protocol/MoovboxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MoovboxProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class MoovboxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MoovboxProtocolDecoder(null); + var decoder = inject(new MoovboxProtocolDecoder(null)); verifyPositions(decoder, request(HttpMethod.POST, "/", buffer("\n\n3\n\n100.726257\n13.821351\n9.500000\n0.000000\n0.064000\n-27.300000\n0.000000\n9\n\n"))); diff --git a/src/test/java/org/traccar/protocol/MotorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MotorProtocolDecoderTest.java index bd4a97ef4..f3ebb8e5c 100644 --- a/src/test/java/org/traccar/protocol/MotorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MotorProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class MotorProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MotorProtocolDecoder(null); + var decoder = inject(new MotorProtocolDecoder(null)); verifyPosition(decoder, text( "341200007E7E00007E7E020301803955352401161766210162090501010108191625132655351234567F12345F")); diff --git a/src/test/java/org/traccar/protocol/MtxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MtxProtocolDecoderTest.java index 28b5d3be0..8a5e228c7 100644 --- a/src/test/java/org/traccar/protocol/MtxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MtxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class MtxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MtxProtocolDecoder(null); + var decoder = inject(new MtxProtocolDecoder(null)); verifyPosition(decoder, text( "#MTX,353815011138124,20101226,195550,41.6296399,002.3611174,000,035,000000.00,X,X,1111,000,0,0")); diff --git a/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java index 301b6102b..68a68c9e8 100644 --- a/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MxtProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class MxtProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new MxtProtocolDecoder(null); + var decoder = inject(new MxtProtocolDecoder(null)); verifyPosition(decoder, binary( "01a631a7627b00087dc41c40850006aab70affecdf23fd32200080000600000000000000000000001b2ff03b1bb9c4c60214f40100050000006c2d0000f427600051051101de0704")); diff --git a/src/test/java/org/traccar/protocol/NavigilProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavigilProtocolDecoderTest.java index 60d88999e..8eda687cc 100644 --- a/src/test/java/org/traccar/protocol/NavigilProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavigilProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NavigilProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NavigilProtocolDecoder(null); + var decoder = inject(new NavigilProtocolDecoder(null)); verifyNull(decoder, binary( "01004300040020000000f60203080200e7cd0f510c0000003b00000000000000")); diff --git a/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java index b1282cac7..5c841b211 100644 --- a/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class NavisProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeNtcb() throws Exception { - var decoder = new NavisProtocolDecoder(null); + var decoder = inject(new NavisProtocolDecoder(null)); verifyNull(decoder, binary( "404E5443010000007B000000130044342A3E533A383631373835303035323035303739")); @@ -41,7 +41,7 @@ public class NavisProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeFlex10() throws Exception { - var decoder = new NavisProtocolDecoder(null); + var decoder = inject(new NavisProtocolDecoder(null)); verifyNull(decoder, binary( "404e544301000000c9b5f602130046c52a3e533a383639363936303439373232383235")); @@ -60,7 +60,7 @@ public class NavisProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeFlex20() throws Exception { - var decoder = new NavisProtocolDecoder(null); + var decoder = inject(new NavisProtocolDecoder(null)); verifyNull(decoder, binary( "404e544301000000a9eef602130043fb2a3e533a383639363936303439373337333835")); diff --git a/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java index e73c173b7..d15d01cc0 100644 --- a/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java @@ -8,7 +8,7 @@ public class NavisetFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NavisetFrameDecoder(); + var decoder = inject(new NavisetFrameDecoder()); verifyFrame( binary("1310e4073836383230343030353935383436362a060716"), diff --git a/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java index df4e57e8d..d7643b50c 100644 --- a/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NavisetProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NavisetProtocolDecoder(null); + var decoder = inject(new NavisetProtocolDecoder(null)); verifyNull(decoder, binary( "1310e4073836383230343030353935383436362a060716")); diff --git a/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java index 562b220d4..360f92447 100644 --- a/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavtelecomFrameDecoderTest.java @@ -9,7 +9,7 @@ public class NavtelecomFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NavtelecomFrameDecoder(); + var decoder = inject(new NavtelecomFrameDecoder()); verifyFrame( binary("404e5443010000000000000013004e452a3e533a383636373935303331343130363839"), @@ -28,7 +28,7 @@ public class NavtelecomFrameDecoderTest extends ProtocolTest { @Test public void testDecodeFull() throws Exception { - var decoder = new NavtelecomFrameDecoder(); + var decoder = inject(new NavtelecomFrameDecoder()); verifyFrame( binary("404e5443010000000000000013004e452a3e533a383636373935303331343130363839"), diff --git a/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java index fd22049fc..301a72b2a 100644 --- a/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavtelecomProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NavtelecomProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NavtelecomProtocolDecoder(null); + var decoder = inject(new NavtelecomProtocolDecoder(null)); verifyNull(decoder, binary( "404e5443010000000000000013004e452a3e533a383636373935303331343130363839")); diff --git a/src/test/java/org/traccar/protocol/NeosProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NeosProtocolDecoderTest.java index b77bdf658..4e9e55f62 100644 --- a/src/test/java/org/traccar/protocol/NeosProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NeosProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NeosProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NeosProtocolDecoder(null); + var decoder = inject(new NeosProtocolDecoder(null)); verifyPosition(decoder, text( ">12345678,1,1,070201,144111,W05829.2613,S3435.2313,,00,034,25,00,126-000,0,3,11111111*2d!\r\n")); diff --git a/src/test/java/org/traccar/protocol/NetProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NetProtocolDecoderTest.java index 9ab4aea4f..239d892f8 100644 --- a/src/test/java/org/traccar/protocol/NetProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NetProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NetProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NetProtocolDecoder(null); + var decoder = inject(new NetProtocolDecoder(null)); verifyPosition(decoder, text( "@L03686090604017761712271020161807037078881037233751000000010F850036980A4000")); diff --git a/src/test/java/org/traccar/protocol/NiotProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NiotProtocolDecoderTest.java index 7707094a5..03aaa49aa 100644 --- a/src/test/java/org/traccar/protocol/NiotProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NiotProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NiotProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NiotProtocolDecoder(null); + var decoder = inject(new NiotProtocolDecoder(null)); verifyPosition(decoder, binary( "585880004c08675430347318522007161451458024b28003f566ee00000328f8000748217ffc500729007a280000000000160001383932353430323130363431363738373136323100050002004e00570d"), diff --git a/src/test/java/org/traccar/protocol/NoranProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NoranProtocolDecoderTest.java index a30847160..3f1ec7aee 100644 --- a/src/test/java/org/traccar/protocol/NoranProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NoranProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NoranProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NoranProtocolDecoder(null); + var decoder = inject(new NoranProtocolDecoder(null)); verifyNull(decoder, binary( "0d0a2a4b57000d000080010d0a")); diff --git a/src/test/java/org/traccar/protocol/NvsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NvsFrameDecoderTest.java index 76c7cafb9..dd5e1d9b9 100644 --- a/src/test/java/org/traccar/protocol/NvsFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NvsFrameDecoderTest.java @@ -10,7 +10,7 @@ public class NvsFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NvsFrameDecoder(); + var decoder = inject(new NvsFrameDecoder()); assertEquals( binary("0012333537303430303630303137383234312e38"), diff --git a/src/test/java/org/traccar/protocol/NvsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NvsProtocolDecoderTest.java index ed4008d47..61d050679 100644 --- a/src/test/java/org/traccar/protocol/NvsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NvsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NvsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NvsProtocolDecoder(null); + var decoder = inject(new NvsProtocolDecoder(null)); verifyNull(decoder, binary( "0012333537303430303630303137383234312e38")); diff --git a/src/test/java/org/traccar/protocol/NyitechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NyitechProtocolDecoderTest.java index 81de06f89..b3bd9aca7 100644 --- a/src/test/java/org/traccar/protocol/NyitechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NyitechProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class NyitechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new NyitechProtocolDecoder(null); + var decoder = inject(new NyitechProtocolDecoder(null)); verifyPosition(decoder, binary( "4040690030313436383230303238373201201c0c12031a308080801c0c12031a3007d67e7e08aceb841002000000ae08000000000000000000000000001e002900f0ffdd002700f2ffe0002700f2ffe1002400f0ffdf002400f3ffe3008a00ffff01010000a9c70d0a")); diff --git a/src/test/java/org/traccar/protocol/ObdDongleProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ObdDongleProtocolDecoderTest.java index 08ebf9995..8272fe41e 100644 --- a/src/test/java/org/traccar/protocol/ObdDongleProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ObdDongleProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ObdDongleProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ObdDongleProtocolDecoder(null); + var decoder = inject(new ObdDongleProtocolDecoder(null)); verifyNull(decoder, binary( "55550003383634383637303232353131303135010009010011023402010201ABAAAA")); diff --git a/src/test/java/org/traccar/protocol/OigoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OigoProtocolDecoderTest.java index 023158f21..6015f1d18 100644 --- a/src/test/java/org/traccar/protocol/OigoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OigoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OigoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OigoProtocolDecoder(null); + var decoder = inject(new OigoProtocolDecoder(null)); verifyPosition(decoder, binary( "7e002e000000146310002523830400001bfb000369150f310c0591594d062ac0c0141508011303cd63101604fd00000000")); diff --git a/src/test/java/org/traccar/protocol/OkoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OkoProtocolDecoderTest.java index 0df537642..19c96ed9a 100644 --- a/src/test/java/org/traccar/protocol/OkoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OkoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OkoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OkoProtocolDecoder(null); + var decoder = inject(new OkoProtocolDecoder(null)); verifyPosition(decoder, text( "{861001001012919,090745,A,4944.302,N,02353.366,E,0.0,225,251120,7,0.27,F9,11.3,1}")); diff --git a/src/test/java/org/traccar/protocol/OmnicommFrameDecoderTest.java b/src/test/java/org/traccar/protocol/OmnicommFrameDecoderTest.java index c8bbf399a..8e8d9b1cf 100644 --- a/src/test/java/org/traccar/protocol/OmnicommFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OmnicommFrameDecoderTest.java @@ -8,7 +8,7 @@ public class OmnicommFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OmnicommFrameDecoder(); + var decoder = inject(new OmnicommFrameDecoder()); verifyFrame( binary("c08600004566"), diff --git a/src/test/java/org/traccar/protocol/OmnicommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OmnicommProtocolDecoderTest.java index 76b476fc2..5b3b08194 100644 --- a/src/test/java/org/traccar/protocol/OmnicommProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OmnicommProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OmnicommProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OmnicommProtocolDecoder(null); + var decoder = inject(new OmnicommProtocolDecoder(null)); verifyNull(decoder, binary( "c080080061a61915340100001dec")); diff --git a/src/test/java/org/traccar/protocol/OpenGtsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OpenGtsProtocolDecoderTest.java index 9fbd79cbf..5494301d8 100644 --- a/src/test/java/org/traccar/protocol/OpenGtsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OpenGtsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OpenGtsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OpenGtsProtocolDecoder(null); + var decoder = inject(new OpenGtsProtocolDecoder(null)); verifyPosition(decoder, request( "/?id=999000000000003&gprmc=$GPRMC,082202.0,A,5006.747329,N,01416.512315,E,0.0,,131018,1.2,E,A*2E")); diff --git a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java index 7d3068c02..408053496 100644 --- a/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OrbcommProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OrbcommProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OrbcommProtocolDecoder(null); + var decoder = inject(new OrbcommProtocolDecoder(null)); verifyNull(decoder, response( buffer("{\"ErrorID\":0,\"NextStartUTC\":\"\",\"Messages\":null}"))); diff --git a/src/test/java/org/traccar/protocol/OrionProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OrionProtocolDecoderTest.java index 7368a9d4e..f5b98574c 100644 --- a/src/test/java/org/traccar/protocol/OrionProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OrionProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OrionProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OrionProtocolDecoder(null); + var decoder = inject(new OrionProtocolDecoder(null)); verifyPositions(decoder, binary( "5057000137bf6236235a0331b5c6e402a3b5ecff5102980003000e0c1d172936080e0c1d172936b03b01000882050000008e080000000000008c0300940500000084030085030003067600900113150000000000000000000000000000000000000004a4c8")); diff --git a/src/test/java/org/traccar/protocol/OsmAndProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OsmAndProtocolDecoderTest.java index a87b45ec4..3b8a94613 100644 --- a/src/test/java/org/traccar/protocol/OsmAndProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OsmAndProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class OsmAndProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OsmAndProtocolDecoder(null); + var decoder = inject(new OsmAndProtocolDecoder(null)); verifyNotNull(decoder, request( "/?id=123456×tamp=1377177267&cell=257,02,16,2224&cell=257,02,16,2223,-90&wifi=00-14-22-01-23-45,-80&wifi=00-1C-B3-09-85-15,-70")); diff --git a/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java index 1194f7970..edb7d1aad 100644 --- a/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class OutsafeProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OutsafeProtocolDecoder(null); + var decoder = inject(new OutsafeProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{\"device\":\"865303040103725\",\"owner\":\"\",\"data\":{\"cmd\":\"\",\"ms1\":-1,\"ms2\":-1,\"ms3\":0,\"ms4\":0,\"observation\":\"\",\"content\":null},\"time\":1589277568,\"origin\":\"mqgatte\",\"latitude\":19.346855,\"longitude\":-99.29587,\"altitude\":2757,\"heading\":0,\"rssi\":0}"))); diff --git a/src/test/java/org/traccar/protocol/OwnTracksProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OwnTracksProtocolDecoderTest.java index 55b48fb05..03332e7fe 100644 --- a/src/test/java/org/traccar/protocol/OwnTracksProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/OwnTracksProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class OwnTracksProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new OwnTracksProtocolDecoder(null); + var decoder = inject(new OwnTracksProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{\"_type\":\"location\",\"acc\":15,\"alt\":440,\"batt\":46,\"conn\":\"w\",\"lat\":46.0681247,\"lon\":11.1512805,\"t\":\"u\",\"tid\":\"5t\",\"tst\":1551874878,\"vac\":2,\"vel\":0}"))); diff --git a/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java index edf508314..bde464162 100644 --- a/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java @@ -22,7 +22,7 @@ public class PacificTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PacificTrackProtocolDecoder(null); + var decoder = inject(new PacificTrackProtocolDecoder(null)); verifyAttributes(decoder, binary( "FB80019702808835275309000091108181B2C08F0143000E10000000010000001400010192DF0143288063810A8202835584D285B486E68780882D89C38A788BCE8C3A8D3C8E418F809073A008ACA16600A225A0C0000F4240C10003DF2CC200004E20C3004428C0C4000008C6C5000316A4E011314334424A57464758444C35333137373302A086AB569DFE110E02A8811203FF81000190820100")); diff --git a/src/test/java/org/traccar/protocol/PathAwayProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PathAwayProtocolDecoderTest.java index e4c9bf449..97020343f 100644 --- a/src/test/java/org/traccar/protocol/PathAwayProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PathAwayProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class PathAwayProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PathAwayProtocolDecoder(null); + var decoder = inject(new PathAwayProtocolDecoder(null)); verifyPosition(decoder, request( "?UserName=name&Password=pass&LOC=$PWS,1,\"Roger\",,,100107,122846,45.317270,-79.642219,45.00,42,1,\"Comment\",0*58")); diff --git a/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java index b39060420..475ac0125 100644 --- a/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class PiligrimProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PiligrimProtocolDecoder(null); + var decoder = inject(new PiligrimProtocolDecoder(null)); verifyPositions(decoder, request(HttpMethod.POST, "/bingps?imei=868204005544720&csq=18&vout=00&vin=4050&dataid=00000000", diff --git a/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java index 2d134d967..8b15d70a6 100644 --- a/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class PluginProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PluginProtocolDecoder(null); + var decoder = inject(new PluginProtocolDecoder(null)); verifyPosition(decoder, text( "$$STATUS,000000900005,20210521111252,27.171105,-25.600934,62.0,323,0,-1,2,0.000,2147489155,0.00,0,0,0.0,0.0,0,0,0,0,0,0,0,0,0")); diff --git a/src/test/java/org/traccar/protocol/PolteProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PolteProtocolDecoderTest.java index 592267b9e..8bf109d11 100644 --- a/src/test/java/org/traccar/protocol/PolteProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PolteProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class PolteProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PolteProtocolDecoder(null); + var decoder = inject(new PolteProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{\"_id\":\"5f75cf7b02c5023bfc0beaf7\",\"location\":{\"LocationMetrics\":{\"EnvironmentDensity\":1,\"LocationType\":2,\"carrierInfo\":{\"aux\":{\"PLMN\":\"310410\",\"country\":\"United States\",\"name\":\"ATT Wireless Inc\"},\"crs\":{\"PLMN\":\"310410\",\"country\":\"United States\",\"name\":\"ATT Wireless Inc\"}},\"hdop\":1850000,\"leversion\":\"2.2.18-20200729T140651\",\"towercount\":1},\"altitude\":0.0011297669261693954,\"confidence\":783.7972188868215,\"detected_at\":1601556342,\"latitude\":29.77368956725161,\"longitude\":-98.26530342694024,\"towerDB\":\"default\",\"ueToken\":\"ALT12503DE04336CB2E3A4A113FCDE05DF05A6F\",\"uid\":\"WZuDMv5Je\"},\"report\":{\"battery\":{\"count\":555,\"level\":100,\"voltage\":3.52},\"event\":3,\"time\":\"2020-10-01T12:45:48.207Z\"},\"time\":\"2020-10-01T12:45:42Z\",\"ueToken\":\"ALT12503DE04336CB2E3A4A113FCDE05DF05A6F\",\"uid\":\"WZuDMv5Je\"}"))); diff --git a/src/test/java/org/traccar/protocol/PortmanProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PortmanProtocolDecoderTest.java index 37798d960..8bc16d373 100644 --- a/src/test/java/org/traccar/protocol/PortmanProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PortmanProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class PortmanProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PortmanProtocolDecoder(null); + var decoder = inject(new PortmanProtocolDecoder(null)); verifyPosition(decoder, text( "$EXT,P0RTMANGRANT,A,210609201710,N0951.6879W08357.0129,0,0,NA,NA,11,25,174700.25,NA,01820000,108")); diff --git a/src/test/java/org/traccar/protocol/PretraceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PretraceProtocolDecoderTest.java index 8a4f257f5..5dbde7846 100644 --- a/src/test/java/org/traccar/protocol/PretraceProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PretraceProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class PretraceProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PretraceProtocolDecoder(null); + var decoder = inject(new PretraceProtocolDecoder(null)); verifyPosition(decoder, text( "(867967021915915U1110A1701201500102238.1700N11401.9324E000264000000000009001790000000,&P11A4,F1050^47")); diff --git a/src/test/java/org/traccar/protocol/PricolProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PricolProtocolDecoderTest.java index a9373e22e..8c2081641 100644 --- a/src/test/java/org/traccar/protocol/PricolProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PricolProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class PricolProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PricolProtocolDecoder(null); + var decoder = inject(new PricolProtocolDecoder(null)); verifyPosition(decoder, binary( "3c5052493030303350020000011402110b222b0455152e4e001de819ca450000000000000003820249000000000000000000000000000000000000000040003e")); diff --git a/src/test/java/org/traccar/protocol/ProgressProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ProgressProtocolDecoderTest.java index 6e59f2876..9129a3079 100644 --- a/src/test/java/org/traccar/protocol/ProgressProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ProgressProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ProgressProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ProgressProtocolDecoder(null); + var decoder = inject(new ProgressProtocolDecoder(null)); verifyNull(decoder, binary( "020037000100000003003131310f003335343836383035313339303036320f00323530303136333832383531353535010000000100000000000000e6bb97b6")); diff --git a/src/test/java/org/traccar/protocol/PstFrameDecoderTest.java b/src/test/java/org/traccar/protocol/PstFrameDecoderTest.java index 96993b97b..172d85df6 100644 --- a/src/test/java/org/traccar/protocol/PstFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PstFrameDecoderTest.java @@ -8,7 +8,7 @@ public class PstFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PstFrameDecoder(); + var decoder = inject(new PstFrameDecoder()); verifyFrame( binary("2fafac5a050f0000e0022fafac5a01891e882bbfdd06dd577c9865620a0efe524c419f940b6710f5ba0c86e5868ffc97c77eaaf166a31dba63f9894e98a91b9486c94e79ce537359737a5e9385431a590eb20b5115a2b7939e4e66ae"), diff --git a/src/test/java/org/traccar/protocol/PstProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PstProtocolDecoderTest.java index 445c333c1..880caf727 100644 --- a/src/test/java/org/traccar/protocol/PstProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PstProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class PstProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new PstProtocolDecoder(null); + var decoder = inject(new PstProtocolDecoder(null)); verifyPosition(decoder, binary( "2faf97de06000024db0551380cbb08070b040000015a0c09b50177e5100a1822da0d010d0f0451380628101451380cc384b800488a84036901b202d3010001061103ffff00150203523687")); diff --git a/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java index 24cfd316a..a5f5d7e77 100644 --- a/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Pt215ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Pt215ProtocolDecoder(null); + var decoder = inject(new Pt215ProtocolDecoder(null)); verifyNull(decoder, binary( "58580d010359339075435451010d0a")); diff --git a/src/test/java/org/traccar/protocol/Pt3000ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Pt3000ProtocolDecoderTest.java index 44f57601c..f7b278139 100644 --- a/src/test/java/org/traccar/protocol/Pt3000ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt3000ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Pt3000ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Pt3000ProtocolDecoder(null); + var decoder = inject(new Pt3000ProtocolDecoder(null)); verifyPosition(decoder, text( "%356939010012099,$GPRMC,124945.752,A,4436.6245,N,01054.4634,E,0.11,358.52,060408,,,A,+393334347445,N028d"), diff --git a/src/test/java/org/traccar/protocol/Pt502FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Pt502FrameDecoderTest.java index 2559ad145..854c789b8 100644 --- a/src/test/java/org/traccar/protocol/Pt502FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt502FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Pt502FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Pt502FrameDecoder(); + var decoder = inject(new Pt502FrameDecoder()); verifyFrame( binary("24504844302c3936302cffd8ffdb008400140e0f120f0d14121012171514181e32211e1c1c1e3d2c2e243249404c4b47404645505a736250556d5645466488656d777b8182814e608d978c7d96737e817c011517171e1a1e3b21213b7c5346537c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7cffc000110800f0014003012100021101031101ffdd0004000affc401a20000010501010101010100000000000000000102030405060708090a0b100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9fa0100030101010101010101010000000000000102030405060708090a0b1100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00e5292800ef450020a2800a2801d49400b450014b40052e2800a69340094a05007fffd0e5d14b10055b51b00c76a00527273494005250014500251400525001450015347c25003a928010d25007ffd1e52909a00290d0014b40052d0014500145002e297b50018a280109a6d002d2e2803fffd2e7a04da3777a94fbd0025140052500145002514005250014940054e381400b494008690d007fffd3e4f345001486800a5a005a2800a2801680280168a002909e280100cd028016a48937bfb5007fffd4c5038a42280128a004a280128a003ad2500251400945002a8cb0a9a80133450026692803ffd5e4e8a004a2801694500145002d18a005c5140052e280109a69a0029680140abb147b139eb401ffd6c62290d00251400949400114940052500252d002525003e31c93525002521a004a4a00ffd7e4a8a00281400a29d40094b40053ba500252d0018a31400d3cd250018cd2d005ab58777ccdd074ab645007ffd0c72290d00348a2801280"), diff --git a/src/test/java/org/traccar/protocol/Pt502ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Pt502ProtocolDecoderTest.java index a68471c95..f310b2227 100644 --- a/src/test/java/org/traccar/protocol/Pt502ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt502ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Pt502ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Pt502ProtocolDecoder(null); + var decoder = inject(new Pt502ProtocolDecoder(null)); verifyNull(decoder, binary( "24504844302c3936302cffd8ffdb008400140e0f120f0d14121012171514181e32211e1c1c1e3d2c2e243249404c4b47404645505a736250556d5645466488656d777b8182814e608d978c7d96737e817c011517171e1a1e3b21213b7c5346537c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7cffc000110800f0014003012100021101031101ffdd0004000affc401a20000010501010101010100000000000000000102030405060708090a0b100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9fa0100030101010101010101010000000000000102030405060708090a0b1100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00e5292800ef450020a2800a2801d49400b450014b40052e2800a69340094a05007fffd0e5d14b10055b51b00c76a00527273494005250014500251400525001450015347c25003a928010d25007ffd1e52909a00290d0014b40052d0014500145002e297b50018a280109a6d002d2e2803fffd2e7a04da3777a94fbd0025140052500145002514005250014940054e381400b494008690d007fffd3e4f345001486800a5a005a2800a2801680280168a002909e280100cd028016a48937bfb5007fffd4c5038a42280128a004a280128a003ad2500251400945002a8cb0a9a80133450026692803ffd5e4e8a004a2801694500145002d18a005c5140052e280109a69a0029680140abb147b139eb401ffd6c62290d00251400949400114940052500252d002525003e31c93525002521a004a4a00ffd7e4a8a00281400a29d40094b40053ba500252d0018a31400d3cd250018cd2d005ab58777ccdd074ab645007ffd0c72290d00348a2801280")); diff --git a/src/test/java/org/traccar/protocol/Pt60ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Pt60ProtocolDecoderTest.java index ad987240c..b198ac28e 100644 --- a/src/test/java/org/traccar/protocol/Pt60ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Pt60ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Pt60ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Pt60ProtocolDecoder(null); + var decoder = inject(new Pt60ProtocolDecoder(null)); verifyNull(decoder, text( "@B#@|01|006|864891030184954|9425010450971470|20181213093127|2|1|")); diff --git a/src/test/java/org/traccar/protocol/R12wProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/R12wProtocolDecoderTest.java index acb7277b5..a363022f0 100644 --- a/src/test/java/org/traccar/protocol/R12wProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/R12wProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class R12wProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new R12wProtocolDecoder(null); + var decoder = inject(new R12wProtocolDecoder(null)); verifyNull(decoder, text( "$HX,0001,860721009104316,e92c,933402042499509,55792760080,12345678,01,a8d940a9,#,50,")); diff --git a/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java index 22902079a..ff40c19a3 100644 --- a/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RaceDynamicsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RaceDynamicsProtocolDecoder(null); + var decoder = inject(new RaceDynamicsProtocolDecoder(null)); verifyNull(decoder, text( "$GPRMC,12,260819,100708,862549040661129,")); diff --git a/src/test/java/org/traccar/protocol/RadarProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RadarProtocolDecoderTest.java index be1e4de0b..b5a2555b1 100644 --- a/src/test/java/org/traccar/protocol/RadarProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RadarProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RadarProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RadarProtocolDecoder(null); + var decoder = inject(new RadarProtocolDecoder(null)); verifyPositions(decoder, binary( "361800011459015cb497554c01c101ff003500050038000207ff831c04c01f1c00555cb464895cb46487ff7f04eafeffdbd80000079402ead0000000110000000000120d2aff150000000000000002000a00050002436c61726f0000000000008b00000003764500037653005207ff831c04c01f1c00555cb4648a5cb46489ff7f04eafeffdbd80000079402ead0000000010000000000120e00ff150000000000000002000800060002436c61726f0000000000008d00000003764600037654000207ff831c04c01f1c00555cb464d85cb464d7ff7f04eafeffdbd80000079402ead0000000110000000000120e2aff150000000000000002000700070003436c61726f0000000000008d000000037694000376a2005207ff831c04c01f1c00555cb464d95cb464d9ff7f04eafeffdbd80000079402eac0000000010000000000120e00ff150000000000000002000700070003436c61726f0000000000008d000000037695000376a3000207ff831c04c01f1c00555cb465065cb46504ff7f04eafeffdbd80000079402ead0000000110000000000120e2aff150000000000000000000500060005436c61726f0000000000008d0000000376c2000376d07ed7")); diff --git a/src/test/java/org/traccar/protocol/RaveonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RaveonProtocolDecoderTest.java index 1b111ee5d..3da671dbf 100644 --- a/src/test/java/org/traccar/protocol/RaveonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RaveonProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RaveonProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RaveonProtocolDecoder(null); + var decoder = inject(new RaveonProtocolDecoder(null)); verifyPosition(decoder, text( "$PRAVE,0001,0001,3308.9051,-11713.1164,195348,1,10,168,31,13.3,3,-83,0,0,,1003.4*66")); diff --git a/src/test/java/org/traccar/protocol/RecodaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RecodaProtocolDecoderTest.java index 803cfb48a..5bdfd6816 100644 --- a/src/test/java/org/traccar/protocol/RecodaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RecodaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RecodaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RecodaProtocolDecoder(null); + var decoder = inject(new RecodaProtocolDecoder(null)); verifyNull(decoder, binary( "01100020480000000300000030393535360000000000000001000000303030303000000000000000000000000000000000000000006100004531313037353500ffffffffffff0000")); diff --git a/src/test/java/org/traccar/protocol/RetranslatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RetranslatorProtocolDecoderTest.java index 4af77cfbf..eb591a5f6 100644 --- a/src/test/java/org/traccar/protocol/RetranslatorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RetranslatorProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RetranslatorProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RetranslatorProtocolDecoder(null); + var decoder = inject(new RetranslatorProtocolDecoder(null)); verifyPosition(decoder, binary( "74000000333533393736303133343435343835004B0BFB70000000030BBB000000270102706F73696E666F00A027AFDF5D9848403AC7253383DD4B400000000000805A40003601460B0BBB0000001200047077725F657874002B8716D9CE973B400BBB00000011010361766C5F696E707574730000000001")); diff --git a/src/test/java/org/traccar/protocol/RitiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RitiProtocolDecoderTest.java index e0890a5fc..0d7eeb0df 100644 --- a/src/test/java/org/traccar/protocol/RitiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RitiProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RitiProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RitiProtocolDecoder(null); + var decoder = inject(new RitiProtocolDecoder(null)); verifyPosition(decoder, binary( "3b28a2a2056315316d4000008100000000000000005f710000244750524d432c3138303535332e3030302c412c353532342e383437312c4e2c30313133342e313837382c452c302e30302c2c3032313231332c2c2c412a37340d0a00000000000000000000000000000000040404")); diff --git a/src/test/java/org/traccar/protocol/RoboTrackFrameDecoderTest.java b/src/test/java/org/traccar/protocol/RoboTrackFrameDecoderTest.java index eaf83458d..e4b30538c 100644 --- a/src/test/java/org/traccar/protocol/RoboTrackFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RoboTrackFrameDecoderTest.java @@ -8,7 +8,7 @@ public class RoboTrackFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RoboTrackFrameDecoder(); + var decoder = inject(new RoboTrackFrameDecoder()); verifyFrame( binary("00524f424f545241434b00000000000000383638323034303032323533343136313233343536373839303132312e313261000000312e353761000000312e3030000000003e"), diff --git a/src/test/java/org/traccar/protocol/RoboTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RoboTrackProtocolDecoderTest.java index 40218efdb..db1617c9e 100644 --- a/src/test/java/org/traccar/protocol/RoboTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RoboTrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RoboTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RoboTrackProtocolDecoder(null); + var decoder = inject(new RoboTrackProtocolDecoder(null)); verifyNull(decoder, binary( "00524f424f545241434b00000000000000383638323034303032323533343136313233343536373839303132312e313261000000312e353761000000312e3030000000003e")); diff --git a/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java index 71313e449..b301507fb 100644 --- a/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class RstProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RstProtocolDecoder(null); + var decoder = inject(new RstProtocolDecoder(null)); verifyNull(decoder, text( "RST;A;RST-MINIv2;V7.04;008051261;124;29;04-04-2021 17:27:26;04-04-2021 17:27:26;-1.280811;-47.931755;7353;79;1;14;7315;26;10;0;1855;0;0;0;0;5;5;-1.280821;-47.931747;04-04-2021 17:52:23;6;-1.280863;-47.931770;04-04-2021 18:12:19;5;-1.280844;-47.931763;04-04-2021 17:28:02;5;-1.280900;-47.931770;04-04-2021 19:04:27;4;-1.280843;-47.931747;04-04-2021 18:21:45;04-04-2021 19:29:59;04-04-2021 19:29:59;-1.280770;-47.931595;1;15;0;0;0;0;FIM;")); diff --git a/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java index eca7518a7..89d4a02cc 100644 --- a/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RuptelaProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class RuptelaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new RuptelaProtocolDecoder(null); + var decoder = inject(new RuptelaProtocolDecoder(null)); verifyNull(decoder, binary( "002e000316d53d58d6020f4573303430302e30332e36382e30340000c2b3090d0e950000827b000003e80000003c003c1681")); diff --git a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java index ec795c9eb..2b7f40c82 100644 --- a/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/S168ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class S168ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new S168ProtocolDecoder(null); + var decoder = inject(new S168ProtocolDecoder(null)); verifyAttributes(decoder, text( "S168#861118010104168#00ec#0016#SYNC:0093;STATUS:91,51")); diff --git a/src/test/java/org/traccar/protocol/SabertekFrameDecoderTest.java b/src/test/java/org/traccar/protocol/SabertekFrameDecoderTest.java index ced40acd0..15b1d0451 100644 --- a/src/test/java/org/traccar/protocol/SabertekFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SabertekFrameDecoderTest.java @@ -10,7 +10,7 @@ public class SabertekFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SabertekFrameDecoder(); + var decoder = inject(new SabertekFrameDecoder()); assertEquals( binary("2c3939393939393939392c332c34302c36352c372c302c312c2d32352e3738313636362c32382e3235343730322c34302c3236382c313431342c382c35353632332c"), diff --git a/src/test/java/org/traccar/protocol/SabertekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SabertekProtocolDecoderTest.java index 148695dcd..6aafa325f 100644 --- a/src/test/java/org/traccar/protocol/SabertekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SabertekProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SabertekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SabertekProtocolDecoder(null); + var decoder = inject(new SabertekProtocolDecoder(null)); verifyPosition(decoder, text( ",999999999,3,40,65,7,0,1,-25.781666,28.254702,40,268,1414,8,55623,")); diff --git a/src/test/java/org/traccar/protocol/SanavProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SanavProtocolDecoderTest.java index 223f4f12f..d0ae6fabf 100644 --- a/src/test/java/org/traccar/protocol/SanavProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SanavProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SanavProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SanavProtocolDecoder(null); + var decoder = inject(new SanavProtocolDecoder(null)); verifyPosition(decoder, text( "imei=353197040023431&rmc=$GPRMC,015258.000,A,2457.8101,N,12125.5393,E,0.00,0.00,210111,,*18,AUTO,0300,2.1,10,466,97,34E7,3391,74,466,9 7,3F2D,3391,65,466,97,39C9,3391,79,466,97,3F2C,3391,81,466,97,0000,00 00,83,466,97,0000,0000,85,466,97,0000,0000,85,1,24")); diff --git a/src/test/java/org/traccar/protocol/SanulProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SanulProtocolDecoderTest.java index 23bd6d80b..57398dd84 100644 --- a/src/test/java/org/traccar/protocol/SanulProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SanulProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SanulProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SanulProtocolDecoder(null); + var decoder = inject(new SanulProtocolDecoder(null)); verifyNull(decoder, binary( "aa007020000100000000000033353333353830313831353431313700000000000000000000")); diff --git a/src/test/java/org/traccar/protocol/SatsolProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SatsolProtocolDecoderTest.java index dcd51063c..0fe16377d 100644 --- a/src/test/java/org/traccar/protocol/SatsolProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SatsolProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SatsolProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SatsolProtocolDecoder(null); + var decoder = inject(new SatsolProtocolDecoder(null)); verifyPositions(decoder, binary( "f0e1bf4cb2ec1600e1005f8791e901000000c959515c2cc24a03aeadcd010e01a800250001090201878e92e901000000cb59515c2dc24a03b8adcd018801a8001d0001080201325993e901000000cc59515c2fc24a03bfadcd01ab01a800220001080201dd8194e901000000cd59515c32c24a03ceadcd015801a8002500010802015f3795e905000900ce59515c32c24a03d8adcd01f600a700250001091401000000000000000000863496e901000000cf59515c34c24a03ddadcd019b00a700280001090201714197e904000600cf59515c34c24a03ddadcd019b00a7002800010a1401becd07001901")); diff --git a/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java index 7e2812714..66d5f5e69 100644 --- a/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class SigfoxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SigfoxProtocolDecoder(null); + var decoder = inject(new SigfoxProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/", buffer("{ \"device\":\"BFE47E\", \"time\":1590497040, \"data\":\"10297eb01e621122070000be\", \"seqNumber\":8, \"deviceTypeId\":\"5ecb8bfac563d620cc9e6798\", \"ack\":false }"))); diff --git a/src/test/java/org/traccar/protocol/SiwiProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SiwiProtocolDecoderTest.java index d264895fc..0d7eb4f16 100644 --- a/src/test/java/org/traccar/protocol/SiwiProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SiwiProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SiwiProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SiwiProtocolDecoder(null); + var decoder = inject(new SiwiProtocolDecoder(null)); verifyPosition(decoder, text( "$SIWI,868957040831465,44,E,,,1,1,1,16.79,0,0,5,A,17.204447,78.355087,534,44,140955,180221,11,1,15,5,4322,0,0,0,0,0,0,1.0,1.6CPTASF_6.60,0!")); diff --git a/src/test/java/org/traccar/protocol/SkypatrolProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SkypatrolProtocolDecoderTest.java index a248056f8..e59e3c3f0 100644 --- a/src/test/java/org/traccar/protocol/SkypatrolProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SkypatrolProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SkypatrolProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SkypatrolProtocolDecoder(null); + var decoder = inject(new SkypatrolProtocolDecoder(null)); verifyNull(decoder, binary( "000a02171101303131373232303031333537393833060200000006202020202020202020312020202020202030313137323230303133353739383320")); diff --git a/src/test/java/org/traccar/protocol/SmartSoleProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SmartSoleProtocolDecoderTest.java index 740d1b62c..258eb0fce 100644 --- a/src/test/java/org/traccar/protocol/SmartSoleProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SmartSoleProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SmartSoleProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SmartSoleProtocolDecoder(null); + var decoder = inject(new SmartSoleProtocolDecoder(null)); verifyPosition(decoder, text( "#GTXRP=359366080000385,8,180514200051,34.041981,-118.255806,60,1,1,7,1.80,180514200051,4.16,11")); diff --git a/src/test/java/org/traccar/protocol/SmokeyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SmokeyProtocolDecoderTest.java index d806fd790..de025c18e 100644 --- a/src/test/java/org/traccar/protocol/SmokeyProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SmokeyProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SmokeyProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SmokeyProtocolDecoder(null); + var decoder = inject(new SmokeyProtocolDecoder(null)); verifyAttributes(decoder, binary( "534d0300865101019383025f0403000000000b86250200000c0000028f000102f8cc0900127f08")); diff --git a/src/test/java/org/traccar/protocol/SolarPoweredProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SolarPoweredProtocolDecoderTest.java index 7202aaefb..445628f6d 100644 --- a/src/test/java/org/traccar/protocol/SolarPoweredProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SolarPoweredProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class SolarPoweredProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SolarPoweredProtocolDecoder(null); + var decoder = inject(new SolarPoweredProtocolDecoder(null)); verifyAttribute(decoder, binary( "7e850256553309440011003e81131914030600332301a61ed709209ff40014b89082020f0283100000f908000000440000003d1f19021784114161726f6e34475630312d323030333031057e"), diff --git a/src/test/java/org/traccar/protocol/SpotProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SpotProtocolDecoderTest.java index 7f8e2b58f..03d0e97f0 100644 --- a/src/test/java/org/traccar/protocol/SpotProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SpotProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class SpotProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SpotProtocolDecoder(null); + var decoder = inject(new SpotProtocolDecoder(null)); verifyPositions(decoder, request(HttpMethod.POST, "/", buffer( "\n", diff --git a/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java index 1710ccbb9..0a6ad0163 100644 --- a/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class StarLinkProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new StarLinkProtocolDecoder(null); + var decoder = inject(new StarLinkProtocolDecoder(null)); decoder.setFormat("#IMEI#,#EDT#,#PDT#,#LAT#,#LONG#,#SPD#,#IGN#,#ODO#,#DUR#,#TDUR#,#LAC#,#CID#,#VIN#,#VBAT#,#EID#,#EDSC#,#DRV#,#SATU#,#CSS#,#OUT1#,#OUT2#,#CFL#"); diff --git a/src/test/java/org/traccar/protocol/StarcomProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StarcomProtocolDecoderTest.java index 851d4eac6..84c470970 100644 --- a/src/test/java/org/traccar/protocol/StarcomProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StarcomProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class StarcomProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new StarcomProtocolDecoder(null); + var decoder = inject(new StarcomProtocolDecoder(null)); verifyPosition(decoder, text( "|unit=416307,unittype=5,address=186.167.243.28,kind=14,software_version=14.02.18,hardware_type=17,gps_type=6,longitude=-67.85891,latitude=10.21988,datetime_actual=2019/05/07 21:59:38,network=TCPIP.1|\r\n")); diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index cea079156..e8eecae96 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class StartekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new StartekProtocolDecoder(null); + var decoder = inject(new StartekProtocolDecoder(null)); verifyAttribute(decoder, text( "&&R187,860294046453690,000,0,,220105160656,A,22.994986,72.499711,15,0.9,2,222,55,121135784,404|98|147B|0000376A,24,0000001F,02,00,052E|01A3|0000|0000,1,010000|020000,,853|6|10|105|73|41|125|34|52"), diff --git a/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java index 74b30f9eb..c618ac21c 100644 --- a/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StbProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class StbProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new StbProtocolDecoder(null); + var decoder = inject(new StbProtocolDecoder(null)); verifyAttributes(decoder, text( "{\"attrList\":[{\"id\":\"02101001\",\"value\":\"510101051161205774\"},{\"id\":\"02105001\",\"value\":\"-61\"},{\"id\":\"02102001\",\"value\":\"1\"},{\"doorId\":\"1\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"1\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"1\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"1\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"2\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"2\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"2\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"2\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"3\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"3\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"3\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"3\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"4\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"4\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"4\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"4\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"5\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"5\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"5\",\"id\":\"02103001\",\"value\":\"1\"},{\"doorId\":\"5\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"6\",\"id\":\"02104001\",\"value\":\"2\"},{\"doorId\":\"6\",\"id\":\"02106001\",\"value\":\"BT106002320JPZZ210718002\"},{\"doorId\":\"6\",\"id\":\"02109001\",\"value\":\"98\"},{\"doorId\":\"6\",\"id\":\"02110001\",\"value\":\"100\"},{\"doorId\":\"6\",\"id\":\"01118001\",\"value\":\"27\"},{\"doorId\":\"6\",\"id\":\"01119001\",\"value\":\"26\"},{\"doorId\":\"6\",\"id\":\"01120001\",\"value\":\"28\"},{\"doorId\":\"6\",\"id\":\"02114001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"02116001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"02117001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"01121001\",\"value\":\"2\"},{\"doorId\":\"6\",\"id\":\"02130001\",\"value\":\"0\"},{\"doorId\":\"6\",\"id\":\"01122001\",\"value\":\"4\"},{\"doorId\":\"6\",\"id\":\"02001001\",\"value\":\"000\"},{\"doorId\":\"6\",\"id\":\"02002001\",\"value\":\"000\"},{\"doorId\":\"6\",\"id\":\"01116001\",\"value\":\"20\"},{\"doorId\":\"6\",\"id\":\"01117001\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117002\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117003\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117004\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117005\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117006\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117007\",\"value\":\"3325\"},{\"doorId\":\"6\",\"id\":\"01117008\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117009\",\"value\":\"3325\"},{\"doorId\":\"6\",\"id\":\"01117010\",\"value\":\"3326\"},{\"doorId\":\"6\",\"id\":\"01117011\",\"value\":\"3326\"},{\"doorId\":\"6\",\"id\":\"01117012\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117013\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117014\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117015\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117016\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117017\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117018\",\"value\":\"3323\"},{\"doorId\":\"6\",\"id\":\"01117019\",\"value\":\"3324\"},{\"doorId\":\"6\",\"id\":\"01117020\",\"value\":\"3323\"},{\"batteryId\":\"BT106002320JPZZ210718002\",\"doorId\":\"6\",\"id\":\"02103001\",\"value\":\"1\"},{\"batteryId\":\"BT106002320JPZZ210718002\",\"doorId\":\"6\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"7\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"7\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"7\",\"id\":\"02103001\",\"value\":\"1\"},{\"doorId\":\"7\",\"id\":\"02118001\",\"value\":\"1\"},{\"doorId\":\"8\",\"id\":\"02104001\",\"value\":\"0\"},{\"doorId\":\"8\",\"id\":\"02106001\",\"value\":\"\"},{\"doorId\":\"8\",\"id\":\"02103001\",\"value\":\"0\"},{\"doorId\":\"8\",\"id\":\"02118001\",\"value\":\"1\"},{\"id\":\"02111001\",\"value\":\"0.0\"},{\"id\":\"02112001\",\"value\":\"0.0\"},{\"id\":\"02107001\",\"value\":\"229.1\"},{\"id\":\"02108001\",\"value\":\"1.005\"},{\"id\":\"02120001\",\"value\":\"143.76\"},{\"id\":\"02113001\",\"value\":\"29\"},{\"id\":\"02119001\",\"value\":\"1\"}],\"devId\":\"CHZD08KPD0210425046\",\"isFull\":1,\"msgType\":310,\"txnNo\":\"1636707944778\"}")); diff --git a/src/test/java/org/traccar/protocol/Stl060ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Stl060ProtocolDecoderTest.java index e13f74604..3ef4b1901 100644 --- a/src/test/java/org/traccar/protocol/Stl060ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Stl060ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Stl060ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Stl060ProtocolDecoder(null); + var decoder = inject(new Stl060ProtocolDecoder(null)); verifyPosition(decoder, text( "$1,357804048043099,D001,AP29AW0963,23/02/14,14:06:54,17248488N,078342226E,0.08,193.12,1,1,1,1,1,A"), diff --git a/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java index 99cbeac2f..96fed314c 100644 --- a/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java @@ -8,7 +8,7 @@ public class SuntechFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SuntechFrameDecoder(); + var decoder = inject(new SuntechFrameDecoder()); verifyFrame( binary("81004e05200013383fffff3401000301130a0512080400000000000000000000000047f9d5846a06810072225214010100020300a8002604c1000004b000000470000025a100000000000025c4000000a6"), diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 098758728..7fed55454 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeTemperature() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); decoder.setHbm(true); decoder.setIncludeAdc(true); @@ -39,7 +39,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeRpm() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); decoder.setHbm(true); decoder.setIncludeRpm(true); @@ -53,7 +53,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeHours() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); decoder.setHbm(true); @@ -66,7 +66,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeDriver() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); verifyAttribute(decoder, buffer( "ST300HTE;511050566;45;308;20200909;13:38:38;0;12.50;001354;0.0;1;0;1;1;0;-27.636632;-052.277933;-27.636675;-052.277947;000.000;002.296;0;00000000000000"), @@ -81,7 +81,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); verifyPosition(decoder, buffer( "BLE;1140000053;114;1.0.1;20211001;17:27:09;+28.433465;-82.565891;1;-43;-46;-41;ACB89523EF68;247;0;0")); @@ -262,7 +262,7 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeCrash() throws Exception { - var decoder = new SuntechProtocolDecoder(null); + var decoder = inject(new SuntechProtocolDecoder(null)); verifyAttribute(decoder, binary( "4352523b303931303030303036333b313b313b303135303b16011c150f0ad82f6c0000000000ae037085fbff7700fd00faff6300f30000006800fb000d007100fa00f32f6c00000000005e044a80fcff6f000301e1ff5d00e900e1ff6400e600f4ff5b00ec000a306c00000000002104248306006c000501fcff5b00e00001006e000101eeff4e00e10022306c00000000005c041a7e00006a00010100005d00f800b5ff7cffdf0050009300fc003b44350d"), diff --git a/src/test/java/org/traccar/protocol/SupermateProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SupermateProtocolDecoderTest.java index 29ec670aa..e96c9b62d 100755 --- a/src/test/java/org/traccar/protocol/SupermateProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SupermateProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SupermateProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SupermateProtocolDecoder(null); + var decoder = inject(new SupermateProtocolDecoder(null)); verifyPosition(decoder, text( "2:359672050130411:1:*,00000000,XT,A,10031b,140b28,80ad4c72,81ba2d2c,06ab,238c,020204010000,12,0,0000,0003e6")); diff --git a/src/test/java/org/traccar/protocol/SviasProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SviasProtocolDecoderTest.java index 8a3a74753..fb9053706 100644 --- a/src/test/java/org/traccar/protocol/SviasProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SviasProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SviasProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SviasProtocolDecoder(null); + var decoder = inject(new SviasProtocolDecoder(null)); verifyPosition(decoder, text( "[7061,3041,57,20324277,710,40618,141342,-93155840,-371754060,0,20469,0,16,1,0,0,11323,100,9,,32,4695")); diff --git a/src/test/java/org/traccar/protocol/SwiftechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SwiftechProtocolDecoderTest.java index 10b033985..923b7abfb 100644 --- a/src/test/java/org/traccar/protocol/SwiftechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SwiftechProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class SwiftechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new SwiftechProtocolDecoder(null); + var decoder = inject(new SwiftechProtocolDecoder(null)); verifyPosition(decoder, text( "@@861551041946971,,0,102040,1023.9670,N,07606.8160,E,2.26,151220,A,0127,1,1,03962,00000,#")); diff --git a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java index ba981598d..6ce47db94 100644 --- a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class T55ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new T55ProtocolDecoder(null); + var decoder = inject(new T55ProtocolDecoder(null)); verifyPosition(decoder, text( "QZE,868994033976700,35,28062020,113553,22.13673,114.57263,0,22,A,0")); @@ -121,7 +121,7 @@ public class T55ProtocolDecoderTest extends ProtocolTest { // Maxon devices can send NMEA before identification - var decoder = new T55ProtocolDecoder(null); + var decoder = inject(new T55ProtocolDecoder(null)); verifyNull(decoder, text( "$GPRMC,012006,A,4828.10,N,1353.52,E,0.00,0.00,180915,020.3,E*42")); diff --git a/src/test/java/org/traccar/protocol/T57FrameDecoderTest.java b/src/test/java/org/traccar/protocol/T57FrameDecoderTest.java index dd5929b04..40d5bc9e9 100644 --- a/src/test/java/org/traccar/protocol/T57FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T57FrameDecoderTest.java @@ -8,7 +8,7 @@ public class T57FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new T57FrameDecoder(); + var decoder = inject(new T57FrameDecoder()); verifyFrame( binary("2a5435372346312354353731313137303031233330313131372330303038343323323233342e31333033234e2330383832362e313731342345232b302e3234322c2b302e3130392c2d302e37383923302e30303023362e323030303023413223342e3223"), diff --git a/src/test/java/org/traccar/protocol/T57ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T57ProtocolDecoderTest.java index 376aab1da..2e097562b 100644 --- a/src/test/java/org/traccar/protocol/T57ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T57ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class T57ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new T57ProtocolDecoder(null); + var decoder = inject(new T57ProtocolDecoder(null)); verifyPosition(decoder, text( "*T57#F1#T571117001#301117#000843#2234.1303#N#08826.1714#E#+0.242,+0.109,-0.789#0.000#6.20000#A2#4.2#")); diff --git a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java index 1dd4e8619..b5917e3cc 100644 --- a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class T800xProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new T800xProtocolDecoder(null); + var decoder = inject(new T800xProtocolDecoder(null)); verifyAttributes(decoder, binary( "27271000247bd00860112047066487210407034238000005d7d17365e625ff640a730148")); diff --git a/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java index 56af8830a..36c9d9148 100644 --- a/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class TaipProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TaipProtocolDecoder(null); + var decoder = inject(new TaipProtocolDecoder(null)); verifyAttribute(decoder, text( ">RUS00,111220124402-3138067-06417623000012200FF,000000000000000000000000000,0000000111,15640422,00000,+25.5,00000,51;ID=CST3G0443;#IP1:089F;*34<"), diff --git a/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java index c5de8e62a..b4617cb61 100644 --- a/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TechTltProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TechTltProtocolDecoder(null); + var decoder = inject(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\r\n"), diff --git a/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java index dc4afb784..36c3b578b 100644 --- a/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TechtoCruzFrameDecoderTest.java @@ -10,7 +10,7 @@ public class TechtoCruzFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TechtoCruzFrameDecoder(); + var decoder = inject(new TechtoCruzFrameDecoder()); assertEquals( buffer("$$A35,RESPO|G33|8612345678910|CRUZ,*E3"), diff --git a/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java index 4cef682b4..459401469 100644 --- a/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TechtoCruzProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TechtoCruzProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TechtoCruzProtocolDecoder(null); + var decoder = inject(new TechtoCruzProtocolDecoder(null)); verifyPosition(decoder, text( "$$A120,8612345678910,211005105836,A,FLEX,KCB 947C,000.0,0,-1.38047,S,36.93951,E,1648.4,243.140,21,28,12.1,3.7,0,1,0,0,0,*F6")); diff --git a/src/test/java/org/traccar/protocol/TekFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TekFrameDecoderTest.java index f315e6432..98b2b80c4 100644 --- a/src/test/java/org/traccar/protocol/TekFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TekFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TekFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TekFrameDecoder(); + var decoder = inject(new TekFrameDecoder()); verifyFrame( binary("020315048715E70861074028023219026200400A0340002C007F0009000000000000000000402842064028420641284206402844064128440640284406402844064028440641284406402844060010010C04052B000253000000000001060A0000000000000228330000FF0000FF360014B394"), diff --git a/src/test/java/org/traccar/protocol/TekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TekProtocolDecoderTest.java index a371ffe6b..17910a8d6 100644 --- a/src/test/java/org/traccar/protocol/TekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TekProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TekProtocolDecoder(null); + var decoder = inject(new TekProtocolDecoder(null)); verifyPosition(decoder, binary( "0501E304E00E76086107502100455111492C33332C3137303935342E302C353235352E393933344E2C30303833322E34333935572C322E312C3133342E382C322C302E30302C302E302C302E302C3234303931352C30362C3C45")); diff --git a/src/test/java/org/traccar/protocol/TelemaxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TelemaxProtocolDecoderTest.java index 8c3650f4e..9f36b3f96 100644 --- a/src/test/java/org/traccar/protocol/TelemaxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TelemaxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TelemaxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TelemaxProtocolDecoder(null); + var decoder = inject(new TelemaxProtocolDecoder(null)); verifyNull(decoder, text( "%067374070128")); diff --git a/src/test/java/org/traccar/protocol/TelicFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TelicFrameDecoderTest.java index 125b61d48..dc6cc58c6 100644 --- a/src/test/java/org/traccar/protocol/TelicFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TelicFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TelicFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TelicFrameDecoder(); + var decoder = inject(new TelicFrameDecoder()); verifyFrame( binary("303032363230333339337c3232367c31307c303032303034303130"), diff --git a/src/test/java/org/traccar/protocol/TelicProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TelicProtocolDecoderTest.java index 03824d91b..214bb06c7 100644 --- a/src/test/java/org/traccar/protocol/TelicProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TelicProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TelicProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TelicProtocolDecoder(null); + var decoder = inject(new TelicProtocolDecoder(null)); verifyNull(decoder, text( "0026355565071347499|206|01|001002008")); diff --git a/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java index 7787907b6..d5c7fcdb0 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TeltonikaFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TeltonikaFrameDecoder(); + var decoder = inject(new TeltonikaFrameDecoder()); verifyFrame( binary("000F313233343536373839303132333435"), diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index c3c32369c..0ae4bbfa4 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TeltonikaProtocolDecoder(null, false); + var decoder = inject(new TeltonikaProtocolDecoder(null, false)); verifyNull(decoder, binary( "000F313233343536373839303132333435")); @@ -127,7 +127,7 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { @Test public void testDecodePhoto() throws Exception { - var decoder = new TeltonikaProtocolDecoder(null, false); + var decoder = inject(new TeltonikaProtocolDecoder(null, false)); verifyNull(decoder, binary( "000F313233343536373839303132333435")); @@ -147,7 +147,7 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeConnectionless() throws Exception { - var decoder = new TeltonikaProtocolDecoder(null, true); + var decoder = inject(new TeltonikaProtocolDecoder(null, true)); verifyPositions(decoder, false, binary( "0049cafe0122000f33353734353430373237313339373508010000015d3766f6a800003eef961ec6215e0063006d09003100070401000200f001c8000242381c18003201c7000000e10001")); diff --git a/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java index 6f96f73ad..fc66f53bb 100644 --- a/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeraTrackProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TeraTrackProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TeraTrackProtocolDecoder(null); + var decoder = inject(new TeraTrackProtocolDecoder(null)); verifyAttributes(decoder, text( "{\"MDeviceID\":\"022043756090\",\"DiviceType\":\"1\",\"DataType\":\"1\",\"DataLength\":\"69\",\"DateTime\":\"2022-03-09 10:56:01\",\"Latitude\":\"-6.846451\",\"Longitude\":\"39.316324\",\"LongitudeState\":\"1\",\"LatitudeState\":\"0\",\"Speed\":\"90\",\"Mileage\":\"0\",\"FenceAlarm\":\"0\",\"AreaAlarmID\":\"0\",\"LockCutOff\":\"0\",\"SealTampered\":\"0\",\"MessageAck\":\"1\",\"LockRope\":\"1\",\"LockStatus\":\"1\",\"LockOpen\":\"0\",\"PasswordError\":\"0\",\"CardNo\":\"60000644\",\"IllegalCard\":\"0\",\"LowPower\":\"0\",\"UnCoverBack\":\"0\",\"CoverStatus\":\"1\",\"LockStuck\":\"0\",\"Power\":\"79\",\"GSM\":\"16\",\"IMEI\":\"860922043756090\",\"Index\":\"20\",\"Slave\":[]}")); diff --git a/src/test/java/org/traccar/protocol/ThinkPowerProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ThinkPowerProtocolDecoderTest.java index ff808e667..2085112ec 100644 --- a/src/test/java/org/traccar/protocol/ThinkPowerProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ThinkPowerProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ThinkPowerProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ThinkPowerProtocolDecoder(null); + var decoder = inject(new ThinkPowerProtocolDecoder(null)); verifyNull(decoder, binary( "0103002C01020F38363737333030353038323030343606544C3930344111522D312E302E31372E32303231303431300011C3")); diff --git a/src/test/java/org/traccar/protocol/ThinkRaceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ThinkRaceProtocolDecoderTest.java index 39e7ed473..859dd4f89 100644 --- a/src/test/java/org/traccar/protocol/ThinkRaceProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/ThinkRaceProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class ThinkRaceProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new ThinkRaceProtocolDecoder(null); + var decoder = inject(new ThinkRaceProtocolDecoder(null)); verifyNull(decoder, binary( "48415349483031343730303134382C8000100134363030303134363139363239343806FF")); diff --git a/src/test/java/org/traccar/protocol/Tk102ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tk102ProtocolDecoderTest.java index 2185fda29..3bcc9994a 100644 --- a/src/test/java/org/traccar/protocol/Tk102ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk102ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Tk102ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tk102ProtocolDecoder(null); + var decoder = inject(new Tk102ProtocolDecoder(null)); verifyNull(decoder, buffer( "[\u00800000000000\u000821315452]")); diff --git a/src/test/java/org/traccar/protocol/Tk103FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Tk103FrameDecoderTest.java index 57df2ac5b..87c3d9317 100644 --- a/src/test/java/org/traccar/protocol/Tk103FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103FrameDecoderTest.java @@ -9,7 +9,7 @@ public class Tk103FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tk103FrameDecoder(); + var decoder = inject(new Tk103FrameDecoder()); verifyFrame( binary("283836343735353535353535353535352C445733422C3133313131372C412C353536322E30323837304E2C30313334382E3038313934452C312E3539372C3232333730372C3239312E36352C2D302E31302C3429"), diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java index 321d0cb50..6c01c14f7 100644 --- a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tk103ProtocolDecoder(null); + var decoder = inject(new Tk103ProtocolDecoder(null)); verifyPosition(decoder, text( "(868822040452227,DW3B,150421,A,4154.51607N,45.78950E,0.050,103142,0.000,595.200,7,0)")); diff --git a/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java index b747fa960..40d9ff34d 100644 --- a/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Tlt2hProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tlt2hProtocolDecoder(null); + var decoder = inject(new Tlt2hProtocolDecoder(null)); verifyNull(decoder, text( "#860517049471362#MT700#0000#AUTO#1\r\n", diff --git a/src/test/java/org/traccar/protocol/TlvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TlvProtocolDecoderTest.java index 54d66dac9..d6d1b7275 100644 --- a/src/test/java/org/traccar/protocol/TlvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TlvProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TlvProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TlvProtocolDecoder(null); + var decoder = inject(new TlvProtocolDecoder(null)); verifyNull(decoder, binary( "30430f383630323437303330303934333931ff10393233323132323030303834353433340f533636385f415f56312e30315f454eff1130303a30433a45373a30303a30303a30300132")); diff --git a/src/test/java/org/traccar/protocol/TmgFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TmgFrameDecoderTest.java index 886470745..9cdcb6169 100644 --- a/src/test/java/org/traccar/protocol/TmgFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TmgFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TmgFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TmgFrameDecoder(); + var decoder = inject(new TmgFrameDecoder()); verifyNull( decoder.decode(null, null, binary("2424242424"))); diff --git a/src/test/java/org/traccar/protocol/TmgProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TmgProtocolDecoderTest.java index 722df5306..6d3c36005 100644 --- a/src/test/java/org/traccar/protocol/TmgProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TmgProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TmgProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TmgProtocolDecoder(null); + var decoder = inject(new TmgProtocolDecoder(null)); verifyPosition(decoder, text( "$loc,869309013800417,08032014,094459,1,2826.1956,N,07659.7690,E,0.0,2.5,4441,31,6,95,1,LLLL,NNTN,HH,0.15,0.26,HR38AU1389,0,SW0.1a")); diff --git a/src/test/java/org/traccar/protocol/TopflytechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TopflytechProtocolDecoderTest.java index dbc7210e0..b49345a42 100644 --- a/src/test/java/org/traccar/protocol/TopflytechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TopflytechProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TopflytechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TopflytechProtocolDecoder(null); + var decoder = inject(new TopflytechProtocolDecoder(null)); verifyPosition(decoder, text( "(880316890094910BP00XG00b600000000L00074b54S00000000R0C0F0014000100f0130531152205A0706.1395S11024.0965E000.0251.25")); diff --git a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java index e8da93006..5e7ec1136 100644 --- a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class TopinProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TopinProtocolDecoder(null); + var decoder = inject(new TopinProtocolDecoder(null)); verifyNull(decoder, binary( "787801080D0A")); diff --git a/src/test/java/org/traccar/protocol/TotemFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TotemFrameDecoderTest.java index 95949c51b..175c32848 100644 --- a/src/test/java/org/traccar/protocol/TotemFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TotemFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TotemFrameDecoder(); + var decoder = inject(new TotemFrameDecoder()); verifyFrame( binary("24243030323542423836323031303033373239343836313345"), diff --git a/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java index e16774782..83498b5ac 100644 --- a/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TotemProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TotemProtocolDecoder(null); + var decoder = inject(new TotemProtocolDecoder(null)); verifyPosition(decoder, text( "$$0112E5864606045334223|201112223514,-68.923106,-22.455926,$Cloud,1738,621,730,12100,0,0,255,0,40,40,0,0,255,|13")); diff --git a/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java index def280b04..c4513cbdc 100644 --- a/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Tr20ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tr20ProtocolDecoder(null); + var decoder = inject(new Tr20ProtocolDecoder(null)); verifyPosition(decoder, text( "%%TR20GRANT,L,210602170135,N0951.1733W08356.7672,000,000,C80:F0,00020008,108,CFG:6980.00|")); diff --git a/src/test/java/org/traccar/protocol/Tr900ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tr900ProtocolDecoderTest.java index d3d35b356..96ddf4175 100644 --- a/src/test/java/org/traccar/protocol/Tr900ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tr900ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Tr900ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tr900ProtocolDecoder(null); + var decoder = inject(new Tr900ProtocolDecoder(null)); verifyPosition(decoder, text( ">00001001,4,1,150626,131252,W05830.2978,S3137.2783,,00,348,18,00,003-000,0,3,11111011*3b!"), diff --git a/src/test/java/org/traccar/protocol/TrackboxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrackboxProtocolDecoderTest.java index caac520e1..10603db1c 100644 --- a/src/test/java/org/traccar/protocol/TrackboxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrackboxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TrackboxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TrackboxProtocolDecoder(null); + var decoder = inject(new TrackboxProtocolDecoder(null)); verifyNull(decoder, text( "a=connect&v=11&i=111111111111111")); diff --git a/src/test/java/org/traccar/protocol/TrakMateProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrakMateProtocolDecoderTest.java index ef99527d7..7542b3456 100644 --- a/src/test/java/org/traccar/protocol/TrakMateProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrakMateProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TrakMateProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TrakMateProtocolDecoder(null); + var decoder = inject(new TrakMateProtocolDecoder(null)); verifyPosition(decoder, text( "^TMSTP|352984083995323|116|13.07809|77.55979|131508|131118|0.0|146.51|7|0|71 -2 248|0|13.1|0.0|10.5|1|0|0|0|#")); diff --git a/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java index 80e6a6e81..a093d94e9 100644 --- a/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TramigoFrameDecoderTest.java @@ -8,7 +8,7 @@ public class TramigoFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TramigoFrameDecoder(); + var decoder = inject(new TramigoFrameDecoder()); verifyFrame( binary("8000ed2bb0009c000101bee000050b09633d925b5472616d69676f3a205472697020737461727465642c2053686f636b2053656e736f722c206174204b696e6720437265656b20526f61642d46726565746f776e205374726565742c20506f727420486172636f7572742c205269766572732c204e472c20342e37363336312c20372e30313836382c2030373a31383a333620536570203320454f46"), diff --git a/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java index 8b556b356..c2d13d199 100644 --- a/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TramigoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TramigoProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TramigoProtocolDecoder(null); + var decoder = inject(new TramigoProtocolDecoder(null)); verifyAttributes(decoder, binary( "8000c426b000a6000101c557037598050d5c8a595472616d69676f3a204d6f76696e672c20302e3132206b6d2045206f66204c617275742054696e2049736c616d6963205072696d617279205363686f6f6c2c2054616970696e672c20506572616b2c204d592c20342e38333134392c203130302e37333038352c204e572077697468207370656564203130206b6d2f682c2030303a34393a30382041756720392020454f46")); diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java index 33d4e0124..6dc28d89e 100644 --- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TrvProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TrvProtocolDecoder(null); + var decoder = inject(new TrvProtocolDecoder(null)); verifyNull(decoder, text( "TRVAP00352121088015548")); diff --git a/src/test/java/org/traccar/protocol/Tt8850ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tt8850ProtocolDecoderTest.java index 5d0e86a3f..3f5c60daa 100644 --- a/src/test/java/org/traccar/protocol/Tt8850ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tt8850ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Tt8850ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Tt8850ProtocolDecoder(null); + var decoder = inject(new Tt8850ProtocolDecoder(null)); verifyPosition(decoder, text( "\u0000\u0004,007F,0,GTFRI,020102,867844000667538,4142726856,0,0,1,3,1.6,0,997.3,-66.830786,10.483394,20171212171418,0734,0004,041A,4220,69,20171212171657,FF61")); diff --git a/src/test/java/org/traccar/protocol/TytanProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TytanProtocolDecoderTest.java index 1cab0f8b1..de6f3a6ff 100644 --- a/src/test/java/org/traccar/protocol/TytanProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TytanProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TytanProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TytanProtocolDecoder(null); + var decoder = inject(new TytanProtocolDecoder(null)); verifyPositions(decoder, binary( "B500192000001405125652CA9B1A325FC98D11A9990018020118FC0D")); diff --git a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java index fba8f7db4..72f5dadd8 100644 --- a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class TzoneProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new TzoneProtocolDecoder(null); + var decoder = inject(new TzoneProtocolDecoder(null)); verifyAttributes(decoder, binary( "545a004d24240407010d0000018032100000031515090c052c2100000022030a033400201347000056860a03340020134700002feb0a03340020134700007d96000baa10211f01810127022d000001ebe00d0a")); diff --git a/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java b/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java index 77afbb50f..534287e0a 100644 --- a/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java @@ -8,7 +8,7 @@ public class UlbotechFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new UlbotechFrameDecoder(); + var decoder = inject(new UlbotechFrameDecoder()); verifyFrame( binary("f8010103515810532780699f7e2e3f010e015ee4c906bde45c00000000008b0304004000000404002c776005060373193622110b00240b00fee8ffff807dffff606d0b00fee9af000000af0000000b00feee7d78807dffffffff100101cc2af8"), diff --git a/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java index b7c6d2d45..52f2520cc 100644 --- a/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class UlbotechProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new UlbotechProtocolDecoder(null); + var decoder = inject(new UlbotechProtocolDecoder(null)); verifyPosition(decoder, binary( "f801010353323083177450a703f6f0010efe55a31a0923d01400050070007003040a42000004040070cca00506039b1876220f060800000000000000000725310553410c0c9e310d05310f4641100440311119411f00476101810f8000310487411f00480804203a14c009033320159310f8")); diff --git a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java index 8c12f48f7..3464a6fee 100644 --- a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class UproProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new UproProtocolDecoder(null); + var decoder = inject(new UproProtocolDecoder(null)); verifyPosition(decoder, buffer( "*HQ201999999,BA&A1656512233362911356523660000230618&B0100060010&C00000<6<&F0000&R2405&V0109&W0000003E&K00100&T65&I54600027A00FCB6227A00FCA5727A00E955327A00E8B5327A00F9748&Y54600027A000000FCB6227A000000FCA5727A000000E955327A000000E8B5327A000000F9748&b00A7E81007607#")); diff --git a/src/test/java/org/traccar/protocol/UuxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UuxProtocolDecoderTest.java index 753063d26..40776278d 100644 --- a/src/test/java/org/traccar/protocol/UuxProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UuxProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class UuxProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new UuxProtocolDecoder(null); + var decoder = inject(new UuxProtocolDecoder(null)); verifyNull(decoder, binary( "81910b01ff")); diff --git a/src/test/java/org/traccar/protocol/V680ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/V680ProtocolDecoderTest.java index 59b6dbea9..105dc8339 100644 --- a/src/test/java/org/traccar/protocol/V680ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/V680ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class V680ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new V680ProtocolDecoder(null); + var decoder = inject(new V680ProtocolDecoder(null)); verifyPosition(decoder, text( "#867967020910610#01234567890#1#0000#AUT#1#0500000000120000#114.036291,E,22.665795,N,111.00,000.00#111116#193333##"), diff --git a/src/test/java/org/traccar/protocol/VisiontekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/VisiontekProtocolDecoderTest.java index b079346c9..042b66cae 100644 --- a/src/test/java/org/traccar/protocol/VisiontekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/VisiontekProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class VisiontekProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new VisiontekProtocolDecoder(null); + var decoder = inject(new VisiontekProtocolDecoder(null)); verifyPosition(decoder, text( "$1,117,28,01,16,15,05,48,1725.0518N,07824.5298E,0620,11,0,185,2062,0,0,0,1,1,1,1,24,00.0000,00.3740,00.0000,VAJRA V1.00,A")); diff --git a/src/test/java/org/traccar/protocol/VnetProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/VnetProtocolDecoderTest.java index d43176a45..25cc03781 100644 --- a/src/test/java/org/traccar/protocol/VnetProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/VnetProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class VnetProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new VnetProtocolDecoder(null); + var decoder = inject(new VnetProtocolDecoder(null)); verifyNull(decoder, binary( "24240000140029111909062986818303379282604c452e322e30302ea32b020f0000d3552323")); diff --git a/src/test/java/org/traccar/protocol/Vt200FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Vt200FrameDecoderTest.java index 91cc3d317..7d039dc8f 100644 --- a/src/test/java/org/traccar/protocol/Vt200FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Vt200FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Vt200FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Vt200FrameDecoder(); + var decoder = inject(new Vt200FrameDecoder()); verifyFrame( binary("28631037309456208400340102dc0906171616454415760201144494473f920a0c0000030500200100417c1f383a9d1090510000006a00007000000e00180ee129"), diff --git a/src/test/java/org/traccar/protocol/Vt200ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Vt200ProtocolDecoderTest.java index 791751c27..25ce5550a 100644 --- a/src/test/java/org/traccar/protocol/Vt200ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Vt200ProtocolDecoderTest.java @@ -9,7 +9,7 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Vt200ProtocolDecoder(null); + var decoder = inject(new Vt200ProtocolDecoder(null)); verifyPosition(decoder, binary( "28192030961807208200210101b919011818375801245774036424612500160917000003aa008800007b00aa3429")); diff --git a/src/test/java/org/traccar/protocol/VtfmsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/VtfmsFrameDecoderTest.java index c03511160..e381153a2 100644 --- a/src/test/java/org/traccar/protocol/VtfmsFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/VtfmsFrameDecoderTest.java @@ -10,7 +10,7 @@ public class VtfmsFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new VtfmsFrameDecoder(); + var decoder = inject(new VtfmsFrameDecoder()); assertEquals( buffer("(863071010087648,0HK44,00,000,14,2,9,,A,114946,180313,11.0244,076.9768,282,000,00000,00000,K,0000128,1,12.8,,200,2.501,,4.001,0,0,0,0,0,0,0,,)105"), diff --git a/src/test/java/org/traccar/protocol/VtfmsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/VtfmsProtocolDecoderTest.java index 1d4fa7f21..4925d9769 100644 --- a/src/test/java/org/traccar/protocol/VtfmsProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/VtfmsProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class VtfmsProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new VtfmsProtocolDecoder(null); + var decoder = inject(new VtfmsProtocolDecoder(null)); verifyPosition(decoder, text( "(861359037432331,0EF87,00,0,21,2,01,,A,154559,230119,1101.4046,07656.3859,241,000,00078,00000,K,0000812,1,12.7,,,,,,1,0,0,0,1,1,1,+919566531111*+919994462226,)054"), diff --git a/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java b/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java index 91bccb4c0..42464c6fe 100644 --- a/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchFrameDecoderTest.java @@ -8,7 +8,7 @@ public class WatchFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WatchFrameDecoder(); + var decoder = inject(new WatchFrameDecoder()); verifyFrame( binary("5b33472a3335323636313039303134333135302a303030412a4c4b2c302c302c3130305d"), diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 50baaa81a..4d908b750 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -12,7 +12,7 @@ public class WatchProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WatchProtocolDecoder(null); + var decoder = inject(new WatchProtocolDecoder(null)); verifyNull(decoder, binary( "5b5a4a2a3738393436383035303034323639322a303033342a303433392a4a58544b2c302c77617463685f375f32303232303532363039333935342c312c362c2321414d520a0c0a3c3f96d98367e9468ea245320c0a3c3f96d98367e9468ea245320c0a3c3f96d98367e9468ea245320c389814ffcd762fe49d50ae7a2e0cb528aefbf76911df05c2fbe17d050c2200cff77ef0df4d9b4ab9a4340c449814dbe7c63fa82bc3750d800cc48abbffddb0df8e8fda95e5980c49982ff6cf65f9377d02a39c3aaa0c389805f2ff42c1b80e0a0eb1dc0c2998e9defe15cfa3bdbe80d3540c7298c2f6d9239e3eae3c4a81660c490034dbfd513fedad0c2fc3900cc40039b7f71bb0657ba75558c40cd7813b97ff7219777ec7f401260c7d040003bff6f75fdb898a6ba1140cecd127f7f83357cb73a68a5f680cb081d4f6e749e6af8ed367bc480cec1815dfffd2dbed358112af320ccc21179fffbd17a3a61c133b380c920047defc72a784770ec0fe400c383c42f6faebe76fa736e9d1be0c4918e7decddc67ec9afd87ff220cc418e6bffe6cf6c9ac1f83c3900ca6cad1ffe3da24e1be3b547d03c00c6b00b8fee77f60a76d3e7d0292e20c2918b7bfff76387b793d3a36300c7d0400b7fff7f63ae513ac6f74de0c980016fbff7d01f9b30fca67c7220caa982ff6dbd7bf3d8dfed143ec0c44982fdfcb7b517e26f6ea52420c0ed19cfedb438f179d3fc50ec40c008ad2ffff635fe28dc1ec1f860c76cb7d05bffda53eaebe4d201ae20ccccaffbbfd3db4abb6ddf39d0e0c6b00acfeff406fe4a12661caf80c76982fbffffeb17b2f65472f300c7d04c24bf6ef1b10e47f73fc10b40c76036cfecd4e7837145a6a8e900ccccaf2beeba36fbaa36feb60640c7d0400dfffff73bfa3b87d0256a1700c7d04e4efd6efc23b651eb73e77780ccc1813ffffb39f6baa6f3195080c00007afffee0b9df6346ca08d00c6bca7d04feff4d64a7b56f9855da0c769819fbfd954ea5bd7d040ba6420c4c4c09bfffd5f6c57d01930e7d01220cc48a22dffe30bfcbaf08a795140c7d040433b7ff3cba5f3e336a40060cecbd2bfaf775bea7bde7e095ee0cc4caaef7fb623feeaab69eabc20c8c0021bffd1ea4a1b090175a920c7d046445fbdfc1abe910b0ca56160c7d0440cbd7ef03893c7f7d02e1a8c20c85e42dff5fdaa145759d326b5a0ccc4084f75f8eeb7b15e4eb4ff80c6bc22ef7d7eaf8df3b8ff678cc0cca4026f3cf7518fd731ceca3560cec041ffbe7655eaf822f04c4fe0c7d0478e3fbfcb5dfc8a81fdbb9e20cc418e6d7ff777f26affe37cc020cd7977cbff7d0aecb9727be6a0c0c00bde1f2d797fc8754ed09d4ae0cc498279f7e729fcb9eff70c1a60c7d0478e5bfffc67eef953fda69aa0c7200f1bbf7e891ef5a287cb5b80c983629fee5555f739f8a29279a0c76d103bef73f55a6bf89ba8ce40cc46424f6ded9a194167a067d05880cc4780efeffc37fae944d89bfb40c4464bffffb6dd54e8344394a5c0c49781ffffc653feaa31af59ac00cc464cebfd76ae4e8a55d5b5a4a2a3738393436383035303034323639322a303033352a303434332a4a58544b2c302c77617463685f375f32303232303532363039333935342c322c362c5f24fbbc0c7d04983effcfe35fbd8fff7ce6f60c448a1dfbd715bec3b42448e58a0c0e0421bf5f17ebc31a43301bc40c768ababf4f66cf629ee31fe9900c6b6426bf5f4eb7669dacc439140c945733bff9351e7d04ab6be54ef60ccc98bfbffbf67f63b78d8f42880c7d0400c6f7fffab5cbae8e8275da0c0097ffdefff5dfafb0c4727d04980ccc78d1f6ff1a6b7e37631059fa0c760045f3fd853fea877d03aa87440cc40022f7ffa8b5c58f6e80c58e0ccc4c1f9ffff32fa7af87de04560cb09801f6fdd32efcbdad9495b60c6b987d05bff72d61eb687d05a9f9e20cca57c7ffff6cb1fe3387ea596e0c629823dedfbfc50b97965e44ea0c4918ccbfd7cc75e59fff92e9ee0c8c78e7faff707ffda60ec3ada60c30c217befffcb8f3290f06d75e0c0e8a7bb7dff3eec7b7928ef6680c38ca1cdeff272ba012597d051a520c0018dfffeff27d01e369b3bcd7d80c98146eb2fc7f45c38e1ce53e120c3d5700ff7fd44bee28aa089d900c007157bffffe30302d7d0583585c0ccc5747bfe7f73cff7d02de1098240c7d047865f6feca71d70bdfaab6a20cecb946bfd966be74b61a06c6660c441612ffe7eb966a8c2886cf760ccc7827bffd653ff7980a62e9320c00ca98f7fc1b311a3986700cc20c490017bfff70cfe7bb455637320c6228afbf7e6da4c59763b693740cccc2b5fee1951975760e4a9dca0c0000faffdb255f6f86af4be6fc0cccc2ffdfff7d0225efbc847c42760cb48a8fdffbe23ff1a78782cbe60c7d04980cffff6e6dfc75a6c65a500ce62808bfff24f853748a9537400cb4004ebfeb6e70aa4314903e8c0cb46408ff72d62f44945f64897d040cccca7abfff2db5c6bfcc345e700c7d04c24dd6fd5f95638f78974a800cc4caffffffb17d01c36bdd7d047c2e0c7d0436d1f7f8917f83af7fc5c2180c070449f6fe570f128577c8c97d040c7d047813f6df3fd17d026b6790d1b80cc400c9d6d92dc56497843ed10a0c44986effffe13fef8eef7c717a0c7d049872bbfdad3abe2be0d60b240c4900adbf7d02dfa4ef960fdf23580c629845fefc5a650fbf8b0d4cda0c7d040076b7ef273fe78fce983ae40c4a00ded7ff629f7fab4531501c0c6200b7ffedf13fe6a68f01fb6c0cc49809f77fdb91517fb39e8ba00c760009bf7fd6afe7b46921f27a0cecbd1df6faf99120776e807d03fe0c98ca23fbff3749fb5ed3909c160cc44cbbbfffbd70e77d0367bc2e740c499816f77fe2ffe08edd7d048c9e0c940021beff1df0f1338c2f1a3a0c7d040083feebba1c756e5760c2200c94981dfffdf921b92b99909ba40c7d04984ebbdf7ff0c77d025a1fbfc00c7657b3ff77f4befcae2bf625640c62ca53f7fdb35f2e92af3bd5c60c7d049878bbdfc0dfc1bdaa1918000cc404bbbfefb41ee6b50a39bf180c767874f7fb8ee156320ee600020c69981cffffe0fff6bb2764acaa0cec781bfbff7d0324eb9b4b4d5d5b5a4a2a3738393436383035303034323639322a303033362a303433302a4a58544b2c302c77617463685f375f32303232303532363039333935342c332c362c73580c07ca4fbbfff5bec5abcfac465c0c0042a8beff316aed38fe4603dc0c7d04577d04fefdc929f7294ce7520c0c76984dfaff402fe68ebe113b000c7d0436a6fed465ff4f8d8e3306300c44e434f7f79e84abb8fa081be80c983636bef7e128bf7d03d34c71c80cd7982dffd54cac94536beab1320c058bd6bfff701fe69d1a39d1e80c76caedb77ffea0e47febb469440c0098b2bef5e55eed981672b1c40cd800d1bef4bda58daf7d01d309180c08cadffbfc31799f5613fab2da0c7d049828beffa5eea0bd09a14c2e0c0000e59feb5f9dff7f4945e98e0cc40046ffcfe57fb58f7d053dd9e20c7d040047d7ffd38f67aa9db8d38c0c7698d2df5fe2efc6bb0f5a18220c980367bbfd95dae73e3bf2b59a0c49813796fdf5efab9d3ed7d3d80c9800ebd7fdb831ae8f91811e920c7d04ca74bbff5cdcf45605c25f140c013e029fbfe7ffc299376b409a0c7510009e7d02010f68824cccead60cb13b00f7d5821e6c8d594a06880c75ec00f6e782e8f06b0c610d1a0cc09843dfef117fa5b3aef236f40cdcc208ffff4831f83703ca20c00cc09800bf7fd71eec9ba34e3c200c650f6bffd5bc4dbe7ec5b0f1d80c0d1c1f92ef917fa0b96023eac00c8efb1db6bfa42eed9f69051d4e0c8eff23b2fe4486d56ef44f702e0c8ebc1b9657d46eeea852ac337e0c8efb1f96d9877fc9b34c38f1540c121c2796df13577c727f8cedec0ca9107d05afdd6a9d957ab76c02560c121c2dd6bfd33fa5b844f27d02340cb11037b6e3962e6eaf52d6e7460c2b1c3db2dfe61eef9aad3dcc0a0c542e42d763e709fe723a83ae7c0c7cfa56bf7fedb8763c3f8ab2c00ca40022efff2411604d22a485e00c228adcbfdfcd748293c66b0bf20cb10f0097ff806dcf7a0a640d6e0c5a0400b7e3030ef4ae0a6046f80cb82812fe7b04d77e4bab11894a0c541c24b2dd53fea5891e3824420ca9fb26b2d7156fa485049cac420ca91c2d9edb2487526c2e2260fa0ca9bc25b65ff28e41a34232c0f00c8efb25b649e51ec39c0ae6703a0c70f425a6c820dfaf2f8124c8960c80f42794b323aed9ca9b6924be0cb93b278e3e8d929c36bb70b6360c587b27524f85857d056d214841660cda2f278b4c876eb3186e5acc540ce6832f6e3f0d82f81226e6dc3a0c0b922feff50a03d03c98ae28360c03d62befb54ab611de0c8addee0c84d626b7fdb4461556dc0153040c0b0f27ff5781c5c2b32f6762140c49bf2dfaf521969b702ecb11d80c7d050f27cfed75bfab95dc4af3180c011c3d8e7451df80a5cd0948080c7c2e35f2c7b0becca22e50769e0c7c1c3d965e628f46a9a58ae6100c7c2e3b965f4a6b5ebd1436b0b00c7c863eaedf18c7816cdeeed7e20c2b3e3df6b73952b2b1abc048a00c7cfb3db6cd67ae68cda18af9d60c2bff3e96df12ff61b39627cd580c7c863fd6cd810ee595d85ee6645d5b5a4a2a3738393436383035303034323639322a303033372a303433372a4a58544b2c302c77617463685f375f32303232303532363039333935342c342c362c0c7cff3fb65f812fe196dc62d8360c7c2e3db2de738fae9ca7c7236c0c2b2e3d96df6c1d775a3df5a47e0c7c3e3f96fe943dc07e81e170700c75503fb7d6a6197f1b08df85440c5a133ab6d6a0e68f3acb04b7b00cfa293fd6cfc20c390d5265d3c80c581347b278077d03dc22d9e49c680ce64d47924e8dcdffe9be19dc100cb90f4f9e612d2201961c2e111c0c003b4febb58a96c809ab5a71040ce6d759fbddba54b2aa9d9d983e0cc029576ecf1f703099d84994520c4029579e7d0281577073f5629dd80c5a2952b6fed177177d01e57d0175c20cd8647d044f7e3c58aba523ddb0720cb56753d3e9c6799f95938401f60c756414ff5f00fb57bc4d7e111c0c7c085573ef743ee19ca30057e00c752e5ab77e34eec69f3cbe53940c542e4d96d6e7ff03854a9506620c7cff55b6efca197610a86606180c7cfb55b67eb25f4b999c002bf20c7c107d03beeb451fad8d042492740cb8f05eb5ff664f679c1cc991c60ce1671bffd33d9445b57d0584c7d60c07781dfef5e3ee81b45ff8a8c80cc40072b7dfe6fe6e978257253a0cb1131fe6783035868e439b00d80c583b27b17ecb53dd165c3422180c703b2fbeb18d023e14d90304700c3cce2b93cdc2e6b3550a5546160cb13b3b72fe24273859059b52040c224d34edc742f6bb7c877d02b5940cb84d37cdcfcbc3f03a041cf4ac0ca4923a9f3b74e805b235cce8660c759000fbfd90565072aa7d03bb520cb592017f411dcbe80a0cc420360c09d6528fcf2e25b382ee46d75a0ce2e853d3cfb617fd7d023f05e0780c07cc3bbabfa9f6cec5aa48ac600c404208fb678a4cf16a9c09098c0cf14244fbdfc2afe7932fe57d02900c011c369e7d0264a8570a54f9a2e80cb1103daed6249fe59dc888c2ac0cb1103573c5f697be759923ecc80c705f7d059effaaa4b09b976f375a0c804223bbed89767d041693edab180cb49819d7eb5a8573bb10c951540c3c643af74f021f25b6dd3b7d02040c07982bd73fb31fe38f09a227a40c037610ff7d03c6058098fef936a80c03b808debbe055a1a71319128c0c6b8f2e9e3bb52d71c226d3141a0cdab82d7fa9d416167a1cb950020c03c32bb23ee9e3743f3b6853060cc02937adb5157d05f4a6960c1b680c4076365e6b754bda9394a7aa720c06293ef23313fb1b94bcc2c09a0ce676006bbd8e0417941b90d23c0cb9294f7d01fd3d65748cf6d1cc220c03767d035e3a65e6f2514ab1db060ce6d965bf4035f65c79a9e4446a0ce62921dbf46457b56cd65f6c500c584d6bba7ea8166edd6cf7693a0cb939227bfca25f82a7c4202f2e0c06ce2b9a4f0d95f39eb43c22840c06901eef6fd15fe48f452000e00c62023afbffb269beba0ee0ac540ce6ec00f37b8139f2026e80f1440c22501dfe7d017d03ed8c3ff6803f240cc48ae3b7fd725e63a347cd64100c0094f8efdeb0a9f35c83eb06b00c005d5b5a4a2a3738393436383035303034323639322a303033382a303433332a4a58544b2c302c77617463685f375f32303232303532363039333935342c352c362c6647deef2df57fb68fd76b660c44e43cbfefc0beec867d025c3f920cb4507d01ff6f42ee6c1f58a0db0e0c7d045701ff7f19f9f90fdff037c20c4404259efcd47d02a52b7ef6df0e0c7d04d128f3578db14779993109560ce1e41ecffd2851af49256b1ecc0c7d049837ffff707168db3dd1ac240cc09419f7f39a7d013d6ec1b4e55c0cc4881cff5f49f55fadc52285a40c06ce9ad7dbb8349b97031ac3b00c407d049d9bed74dfadad950eab560c06799ffac7a924b18bdf11c3d40c8054a2f777522e65be921a77240c8042a19bff706fe5b7e3e7d0360cd82840bff3f4fe429bea0081560c0064419fd9157f8b9c797e92c20cc47fe2b7d5e6ee45bf0524010e0c0894299e7d037e4553bcbbc0989e0c40501bbbdc926f8daf53885e0a0c80971ffee559f5bf98ed54cf140c00581abbffac75b88b14d5e3780c5a046dd66fd7bfe5b7ca749df40c403672bbcfe47ee797860ded5e0cb5502efb7ee2ffc7bbdc27d0880c44ca08fbf7031ecd9321d21ef40cdc9806fefde36f0699ad1569420c22cb1bfbdc974fcb900ab601440c00cb1cfbdfd2f7d2730b0b46680c0b4203dfef309fe0adc121e2080c225829feeb901f25b926343bae0c624204dfff4875b69ceda4df4c0c499886ffe7301e8e8bf9ef0a260cdce408dbef829fe45337e98d860c010800ef76088d8015f3b2c84e0c755c3ecfc898f50fbcdb9344220c7c7d03459349337d01e4949da1b4ec0c7cf046ae6e4a90df3552070a5e0c7cf045d23fbba0951147986eca0c7536426e6ef2ef0b7d01c22fd2960cb8284e9db92d40552988334f200cb8024acdbfea90d13b545fe35e0cb8f04d5e48659d48b97c1096140c7c084f79df4402702126bf358a0cb8a74d4def66535e145638d12e0c543e4d8edfa2531b15a340eb800cb83e4eafbd9031291a8563e4780c54a74ef1c7300da79aa94bb67d050cb8f04eba6fb0325813871511b80ce20ff6fffd404ed58ecf264c8e0c7c0f1cb3fe1a36fb7187c379d00c7c3e52f6727d0261ca8bdd1361b80cb8d64d9a4fb1cfe0aadaaa7d05c40c2b2e44b2bfb9b4dcad9d7d0200280c7c3b47d5db803fc2aee71a77f00c7c1343b2bfa06ee6ad3228f10a0c7c3b4a76477fe7650b0c809ca80c54d74b92dbc327134514d6126e0c7c5f4a8f4f74efaaa5cd0a43bc0c7c104bb64ff5ce604fa2028b680c7cff4aaec7f7a9394cc4c599e60cb8ce52eeb553d215a6a466b4120c750f4fae5f9816c04a0a3f751e0c75e04f73c58e96bb4b925a4c680cb80f4b6e3fe1635614bbdeccbc0c7c3b4faf7e825e42d473ee76800ce298578ffcb61f0af936387bbe0cb800e39bf62410681583e0d2b20cb4987d05ff7f297bf69eaf4cd8b40cb57815bf7f300fcffe9fae966a0cb497acd75fd37f648d00d141a00cc48af9fffe1a3b979b8f8573e80c29bff1bf4b94c6fd7c3eec075e0c7cce1f5d5b5a4a2a3738393436383035303034323639322a303033392a303065352a4a58544b2c302c77617463685f375f32303232303532363039333935342c362c362c8f5cf9f34fa6edceb18c0ca4ce436e7d02d329de94b63eb11a0cb894438f44cf753dbc1a83b4560cb8e44391eff729d4155a231bf40cb59443f373b4288492cd6e38160c5a42049bfec8678ad42bce0c560cb12e39fec3d1fe24b5572ee0be0cb1ce35fe33688455aa74e3ffa40cb1d635df4b704160ae864a7d03440cb10f3267dbf4a21d540ca1051c0cb11337724f8747f5547d054e91660cb1a73692df964f3bbb0758d41a0cfe05b60c314460297eae4185f20cad673ceb6dfa05ddbe0278d5de5d")); @@ -145,7 +145,7 @@ public class WatchProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeVoiceMessage() throws Exception { - var decoder = new WatchProtocolDecoder(null); + var decoder = inject(new WatchProtocolDecoder(null)); var mediaManager = mock(MediaManager.class); when(mediaManager.writeFile(any(), any(), any())).thenReturn("mock.amr"); diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java index 12724c32f..6953784fb 100644 --- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class WialonProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WialonProtocolDecoder(null); + var decoder = inject(new WialonProtocolDecoder(null)); verifyNull(decoder, text( "#L#2.0;42001300083;;CE45")); diff --git a/src/test/java/org/traccar/protocol/WliFrameDecoderTest.java b/src/test/java/org/traccar/protocol/WliFrameDecoderTest.java index 2e0d86a61..45c86ae1a 100644 --- a/src/test/java/org/traccar/protocol/WliFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WliFrameDecoderTest.java @@ -8,7 +8,7 @@ public class WliFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WliFrameDecoder(); + var decoder = inject(new WliFrameDecoder()); verifyFrame( binary("0231000101bba758c900010034000500ff001001258fc9013e80ed00001183350101e20006003200090030000a0032000b003331000c0031000d00343438000e003530000f003100100031303800130032001b003134001c0033392c33352c32382c33382c34302c33372c33332c33382c33352c34322c33372c3335001d003130001e0038002300343235002400303100250031303432320026003336343733002700323800280037002900312c312c312c312c31302e3232352e3135312e3230342c36353533352c302c39392c39392c3235352c3235352c3235352c323535002a0030002c0030003000300032003000330031003400ff001c0214130502061b0101258fc9013e80ed000001e2000000000000004d004500302c323031392f30352f30322c30363a33333a30302c323031392f30352f30322c30363a32363a3230005a003000f100352c302c342c302c2d312c2d3100f2003300f3003100f50038363634323530333137303639323400f600312c302c302c3431322c3000f70038343437373200f80032312c31312c302c302c302c302c2c2c2c2c2c302c3000f9003300fa00393100fb0032313100fc0032313000ff00313535363737383533340003"), diff --git a/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java index 77184f86a..e74b1df06 100644 --- a/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WliProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class WliProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WliProtocolDecoder(null); + var decoder = inject(new WliProtocolDecoder(null)); verifyNull(decoder, binary( "0232776c693a30343930333332303332343103")); diff --git a/src/test/java/org/traccar/protocol/WondexFrameDecoderTest.java b/src/test/java/org/traccar/protocol/WondexFrameDecoderTest.java index 85a878aef..a1cbfe737 100644 --- a/src/test/java/org/traccar/protocol/WondexFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WondexFrameDecoderTest.java @@ -11,7 +11,7 @@ public class WondexFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WondexFrameDecoder(); + var decoder = inject(new WondexFrameDecoder()); assertNull( decoder.decode(null, null, binary("f0d70b0001ca9a3b"))); diff --git a/src/test/java/org/traccar/protocol/WondexProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WondexProtocolDecoderTest.java index 111cc9fbe..72ba8e163 100644 --- a/src/test/java/org/traccar/protocol/WondexProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WondexProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class WondexProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WondexProtocolDecoder(null); + var decoder = inject(new WondexProtocolDecoder(null)); verifyPosition(decoder, buffer( "2005010051,19990925063830,26.106181,44.440225,0,0,0,7,2,0.0,0,,,0")); diff --git a/src/test/java/org/traccar/protocol/WristbandProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WristbandProtocolDecoderTest.java index 10381168e..b901820fe 100644 --- a/src/test/java/org/traccar/protocol/WristbandProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WristbandProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class WristbandProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new WristbandProtocolDecoder(null); + var decoder = inject(new WristbandProtocolDecoder(null)); verifyNotNull(decoder, binary( "000102004459583836383730343034343735303035357c56312e307c317c7b4630342331382c30372c332c3539303139322c33303a31382c30372c332c3539303139322c33307d0d0afffefc")); diff --git a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java index aeca95376..7209a423b 100644 --- a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java @@ -8,7 +8,7 @@ public class Xexun2FrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Xexun2FrameDecoder(); + var decoder = inject(new Xexun2FrameDecoder()); verifyFrame( binary("faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf"), diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java index 9faccec01..840c38b52 100644 --- a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Xexun2ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Xexun2ProtocolDecoder(null); + var decoder = inject(new Xexun2ProtocolDecoder(null)); verifyPositions(decoder, false, binary( "faaf00140a5a8618810536243350005ed8e101005b64622880401b001482060864cc2296f840daa22aa884f008c87483c291efddc4f09fc2f49db3c058ef68005a9abe1ae8299d6449bac4e984e0c1d6baa8469d265ff2b60100cc00080000fb2e0013572a3600000002000000000000faaf")); diff --git a/src/test/java/org/traccar/protocol/XexunFrameDecoderTest.java b/src/test/java/org/traccar/protocol/XexunFrameDecoderTest.java index 43b8bdc0e..9bc39fc97 100644 --- a/src/test/java/org/traccar/protocol/XexunFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/XexunFrameDecoderTest.java @@ -8,7 +8,7 @@ public class XexunFrameDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new XexunFrameDecoder(); + var decoder = inject(new XexunFrameDecoder()); verifyFrame( binary("4750524d432c3230353933352e3030302c412c353134302e343335302c4e2c3530312e303638362c452c302e30302c302e30302c3132313031352c30302c303030302e302c412a37302c462c2c696d65693a3335393538373031343731383339322c"), diff --git a/src/test/java/org/traccar/protocol/XexunProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/XexunProtocolDecoderTest.java index d2caa9c55..f7599b4c3 100644 --- a/src/test/java/org/traccar/protocol/XexunProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/XexunProtocolDecoderTest.java @@ -6,9 +6,9 @@ import org.traccar.ProtocolTest; public class XexunProtocolDecoderTest extends ProtocolTest { @Test - public void testDecode() throws Exception { + public void testDecodeSimple() throws Exception { - var decoder = new XexunProtocolDecoder(null, false); + var decoder = inject(new XexunProtocolDecoder(null, false)); verifyAttributes(decoder, text( "GPRMC,.000,A,0.000000,S,0.0000,W,0.00,0.00,,00,0000.0,A*55,L,,imei:353579010727036,")); @@ -53,7 +53,12 @@ public class XexunProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "GPRMC,043435.000,A,811.299200,S,11339.9500,E,0.93,29.52,160313,00,0000.0,A*65,F,,imei:359585014597923,")); - decoder = new XexunProtocolDecoder(null, true); + } + + @Test + public void testDecodeFull() throws Exception { + + var decoder = inject(new XexunProtocolDecoder(null, true)); verifyPosition(decoder, text( "171007160505,,GPRMC,160505.000,A,5323.4680,N,00252.4202,W,000.0,129.7,071017,,,A*7A,F,ACCStart, imei:864504031916915,10,41.1,F:4.28V,1,135,19824,234,15,0062,B7D5")); diff --git a/src/test/java/org/traccar/protocol/XirgoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/XirgoProtocolDecoderTest.java index f3a56a79d..db9c829aa 100644 --- a/src/test/java/org/traccar/protocol/XirgoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/XirgoProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class XirgoProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeCustom() throws Exception { - var decoder = new XirgoProtocolDecoder(null); + var decoder = inject(new XirgoProtocolDecoder(null)); decoder.setForm("UID,EV,D,T,LT,LN,AL,GSPT,HD,SV,HP,BV,CQ,GS,SI,IG,OT"); @@ -31,7 +31,7 @@ public class XirgoProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeNew() throws Exception { - var decoder = new XirgoProtocolDecoder(null); + var decoder = inject(new XirgoProtocolDecoder(null)); verifyPosition(decoder, text( "$$352054058132185,4001,2017/04/21,00:01:05,32.54659,-116.90670,143.2,0,0,0,598,0.0,12,0.9,765840,7.0,14.5,19,1,1,0011,8.5,63.2,5,21999,184,255,671,207,100,185##")); @@ -59,7 +59,7 @@ public class XirgoProtocolDecoderTest extends ProtocolTest { @Test public void testDecodeOld() throws Exception { - var decoder = new XirgoProtocolDecoder(null); + var decoder = inject(new XirgoProtocolDecoder(null)); verifyPosition(decoder, text( "$$354660046140722,6001,2013/01/22,15:36:18,25.80907,-80.32531,7.1,19,165.2,11,0.8,11.1,17,1,1,3.9,2##"), diff --git a/src/test/java/org/traccar/protocol/Xrb28ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xrb28ProtocolDecoderTest.java index 3197ba854..8ed175a74 100644 --- a/src/test/java/org/traccar/protocol/Xrb28ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xrb28ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Xrb28ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Xrb28ProtocolDecoder(null); + var decoder = inject(new Xrb28ProtocolDecoder(null)); verifyAttributes(decoder, text( "*SCOR,OM,123456789123456,Q0,412,80,28#")); diff --git a/src/test/java/org/traccar/protocol/Xt013ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xt013ProtocolDecoderTest.java index f8ddd35c3..007af984e 100644 --- a/src/test/java/org/traccar/protocol/Xt013ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xt013ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Xt013ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Xt013ProtocolDecoder(null); + var decoder = inject(new Xt013ProtocolDecoder(null)); verifyPosition(decoder, text( "TK,862950021650364,150131090859,+53.267863,+5.767363,0,38,12,0,F,204,08,C94,336C,24,,4.09,1,,,,,,,,"), diff --git a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java index 1b3f6fcbb..35cb3c3fa 100644 --- a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class Xt2400ProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new Xt2400ProtocolDecoder(null); + var decoder = inject(new Xt2400ProtocolDecoder(null)); decoder.setConfig("\n:wycfg pcr[1] 012801030405060708090a1213c8545657585a656e7d2cd055595d5e71797a7b7c7e7f80818285866b\n"); diff --git a/src/test/java/org/traccar/protocol/YwtProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/YwtProtocolDecoderTest.java index 1d29b1282..81afe53a3 100644 --- a/src/test/java/org/traccar/protocol/YwtProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/YwtProtocolDecoderTest.java @@ -8,7 +8,7 @@ public class YwtProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - var decoder = new YwtProtocolDecoder(null); + var decoder = inject(new YwtProtocolDecoder(null)); verifyPosition(decoder, text( "%RP,1222102985:1,170509033842,E102.146563,N14.582175,,0,320,10,0,00-00-00-00-00-00-00-00-00-00-00-00,,1db2-02b3-52004,3>941.523-32,7>1,19>-16,20>30.9V")); -- cgit v1.2.3 From 0202dbf7258df8cbe8168ddc985e774b1cadf964 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 14:48:42 -0700 Subject: Decouple more tests from context --- src/main/java/org/traccar/BaseProtocolDecoder.java | 4 ++ src/main/java/org/traccar/BaseProtocolEncoder.java | 19 ++++- src/main/java/org/traccar/TrackerClient.java | 5 +- src/main/java/org/traccar/TrackerServer.java | 5 +- .../java/org/traccar/protocol/AdmProtocol.java | 3 +- .../java/org/traccar/protocol/AisProtocol.java | 3 +- .../org/traccar/protocol/AlematicsProtocol.java | 3 +- .../java/org/traccar/protocol/AnytrekProtocol.java | 3 +- .../java/org/traccar/protocol/ApelProtocol.java | 3 +- .../java/org/traccar/protocol/AplicomProtocol.java | 3 +- .../java/org/traccar/protocol/AppelloProtocol.java | 3 +- .../java/org/traccar/protocol/AquilaProtocol.java | 3 +- .../java/org/traccar/protocol/Ardi01Protocol.java | 3 +- .../java/org/traccar/protocol/ArknavProtocol.java | 3 +- .../org/traccar/protocol/ArknavX8Protocol.java | 3 +- .../java/org/traccar/protocol/ArmoliProtocol.java | 3 +- .../java/org/traccar/protocol/ArnaviProtocol.java | 3 +- .../java/org/traccar/protocol/AstraProtocol.java | 5 +- .../java/org/traccar/protocol/At2000Protocol.java | 3 +- .../java/org/traccar/protocol/AtrackProtocol.java | 5 +- .../java/org/traccar/protocol/AuroProtocol.java | 3 +- .../org/traccar/protocol/AustinNbProtocol.java | 3 +- .../java/org/traccar/protocol/AutoFonProtocol.java | 3 +- .../org/traccar/protocol/AutoGradeProtocol.java | 3 +- .../org/traccar/protocol/AutoTrackProtocol.java | 3 +- .../java/org/traccar/protocol/AvemaProtocol.java | 3 +- .../java/org/traccar/protocol/Avl301Protocol.java | 3 +- .../java/org/traccar/protocol/B2316Protocol.java | 3 +- .../java/org/traccar/protocol/BceProtocol.java | 3 +- .../org/traccar/protocol/BlackKiteProtocol.java | 3 +- .../java/org/traccar/protocol/BlueProtocol.java | 3 +- .../java/org/traccar/protocol/BoxProtocol.java | 3 +- .../java/org/traccar/protocol/C2stekProtocol.java | 3 +- .../java/org/traccar/protocol/CalAmpProtocol.java | 3 +- .../org/traccar/protocol/CarTrackProtocol.java | 3 +- .../java/org/traccar/protocol/CarcellProtocol.java | 3 +- .../java/org/traccar/protocol/CarscopProtocol.java | 3 +- .../java/org/traccar/protocol/CastelProtocol.java | 5 +- .../traccar/protocol/CastelProtocolEncoder.java | 5 +- .../java/org/traccar/protocol/CautelaProtocol.java | 3 +- .../org/traccar/protocol/CellocatorProtocol.java | 5 +- .../java/org/traccar/protocol/CguardProtocol.java | 3 +- .../org/traccar/protocol/CityeasyProtocol.java | 3 +- .../org/traccar/protocol/ContinentalProtocol.java | 3 +- .../org/traccar/protocol/CradlepointProtocol.java | 3 +- .../java/org/traccar/protocol/DingtekProtocol.java | 3 +- .../java/org/traccar/protocol/DishaProtocol.java | 3 +- .../java/org/traccar/protocol/DmtHttpProtocol.java | 3 +- .../java/org/traccar/protocol/DmtProtocol.java | 3 +- .../java/org/traccar/protocol/DolphinProtocol.java | 3 +- .../java/org/traccar/protocol/Dsf22Protocol.java | 5 +- .../java/org/traccar/protocol/DualcamProtocol.java | 3 +- .../java/org/traccar/protocol/DwayProtocol.java | 3 +- .../org/traccar/protocol/EasyTrackProtocol.java | 3 +- .../java/org/traccar/protocol/EelinkProtocol.java | 5 +- .../java/org/traccar/protocol/EgtsProtocol.java | 3 +- .../java/org/traccar/protocol/EnforaProtocol.java | 5 +- .../java/org/traccar/protocol/EnnfuProtocol.java | 3 +- .../org/traccar/protocol/EnvotechProtocol.java | 3 +- .../java/org/traccar/protocol/EsealProtocol.java | 3 +- .../java/org/traccar/protocol/EskyProtocol.java | 5 +- .../org/traccar/protocol/ExtremTracProtocol.java | 3 +- .../org/traccar/protocol/FifotrackProtocol.java | 3 +- .../java/org/traccar/protocol/FlespiProtocol.java | 3 +- .../java/org/traccar/protocol/FlexApiProtocol.java | 3 +- .../org/traccar/protocol/FlexCommProtocol.java | 3 +- .../traccar/protocol/FlexibleReportProtocol.java | 3 +- .../org/traccar/protocol/FlextrackProtocol.java | 3 +- .../java/org/traccar/protocol/FoxProtocol.java | 3 +- .../java/org/traccar/protocol/FreedomProtocol.java | 3 +- .../org/traccar/protocol/FreematicsProtocol.java | 3 +- .../org/traccar/protocol/FutureWayProtocol.java | 3 +- .../java/org/traccar/protocol/GalileoProtocol.java | 3 +- .../traccar/protocol/GalileoProtocolDecoder.java | 6 +- .../java/org/traccar/protocol/GatorProtocol.java | 5 +- .../java/org/traccar/protocol/GenxProtocol.java | 3 +- .../java/org/traccar/protocol/Gl100Protocol.java | 5 +- .../java/org/traccar/protocol/Gl200Protocol.java | 8 +-- .../org/traccar/protocol/GlobalSatProtocol.java | 3 +- .../org/traccar/protocol/GlobalstarProtocol.java | 3 +- .../java/org/traccar/protocol/GnxProtocol.java | 3 +- .../java/org/traccar/protocol/GoSafeProtocol.java | 5 +- .../java/org/traccar/protocol/GotopProtocol.java | 3 +- .../java/org/traccar/protocol/Gps056Protocol.java | 3 +- .../java/org/traccar/protocol/Gps103Protocol.java | 5 +- .../java/org/traccar/protocol/GpsGateProtocol.java | 3 +- .../org/traccar/protocol/GpsMarkerProtocol.java | 3 +- .../java/org/traccar/protocol/GpsmtaProtocol.java | 3 +- .../java/org/traccar/protocol/GranitProtocol.java | 3 +- .../java/org/traccar/protocol/Gs100Protocol.java | 3 +- .../java/org/traccar/protocol/Gt02Protocol.java | 3 +- .../java/org/traccar/protocol/Gt06Protocol.java | 3 +- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 5 +- .../org/traccar/protocol/Gt06ProtocolEncoder.java | 9 ++- .../java/org/traccar/protocol/Gt30Protocol.java | 3 +- .../java/org/traccar/protocol/H02Protocol.java | 8 +-- .../org/traccar/protocol/H02ProtocolEncoder.java | 5 +- .../java/org/traccar/protocol/HaicomProtocol.java | 3 +- .../java/org/traccar/protocol/HomtecsProtocol.java | 3 +- .../java/org/traccar/protocol/HoopoProtocol.java | 3 +- .../org/traccar/protocol/HuaShengProtocol.java | 3 +- .../java/org/traccar/protocol/HuabaoProtocol.java | 3 +- .../traccar/protocol/HuabaoProtocolEncoder.java | 5 +- .../org/traccar/protocol/HunterProProtocol.java | 3 +- .../java/org/traccar/protocol/IdplProtocol.java | 3 +- .../org/traccar/protocol/IntellitracProtocol.java | 3 +- .../java/org/traccar/protocol/IotmProtocol.java | 3 +- .../java/org/traccar/protocol/ItsProtocol.java | 3 +- .../java/org/traccar/protocol/Ivt401Protocol.java | 3 +- .../java/org/traccar/protocol/JidoProtocol.java | 3 +- .../org/traccar/protocol/JpKorjarProtocol.java | 3 +- .../java/org/traccar/protocol/Jt600Protocol.java | 3 +- .../java/org/traccar/protocol/KenjiProtocol.java | 3 +- .../java/org/traccar/protocol/KhdProtocol.java | 3 +- .../java/org/traccar/protocol/L100Protocol.java | 3 +- .../java/org/traccar/protocol/LacakProtocol.java | 3 +- .../java/org/traccar/protocol/LaipacProtocol.java | 5 +- .../traccar/protocol/LaipacProtocolDecoder.java | 3 +- .../java/org/traccar/protocol/LeafSpyProtocol.java | 3 +- .../java/org/traccar/protocol/M2cProtocol.java | 3 +- .../java/org/traccar/protocol/M2mProtocol.java | 3 +- .../java/org/traccar/protocol/MaestroProtocol.java | 3 +- .../org/traccar/protocol/ManPowerProtocol.java | 3 +- .../org/traccar/protocol/Mavlink2Protocol.java | 6 +- .../org/traccar/protocol/MegastekProtocol.java | 3 +- .../org/traccar/protocol/MeiligaoProtocol.java | 5 +- .../traccar/protocol/MeiligaoProtocolDecoder.java | 5 +- .../traccar/protocol/MeiligaoProtocolEncoder.java | 5 +- .../org/traccar/protocol/MeitrackProtocol.java | 5 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 3 +- .../traccar/protocol/MeitrackProtocolEncoder.java | 5 +- .../org/traccar/protocol/MictrackProtocol.java | 5 +- .../org/traccar/protocol/MilesmateProtocol.java | 3 +- .../org/traccar/protocol/MiniFinderProtocol.java | 3 +- .../org/traccar/protocol/Minifinder2Protocol.java | 3 +- .../org/traccar/protocol/MobilogixProtocol.java | 3 +- .../java/org/traccar/protocol/MoovboxProtocol.java | 3 +- .../java/org/traccar/protocol/MotorProtocol.java | 3 +- .../java/org/traccar/protocol/Mta6Protocol.java | 6 +- .../java/org/traccar/protocol/MtxProtocol.java | 3 +- .../java/org/traccar/protocol/MxtProtocol.java | 3 +- .../java/org/traccar/protocol/NavigilProtocol.java | 3 +- .../java/org/traccar/protocol/NavisProtocol.java | 3 +- .../java/org/traccar/protocol/NavisetProtocol.java | 3 +- .../org/traccar/protocol/NavtelecomProtocol.java | 3 +- .../java/org/traccar/protocol/NeosProtocol.java | 3 +- .../java/org/traccar/protocol/NetProtocol.java | 3 +- .../java/org/traccar/protocol/NiotProtocol.java | 3 +- .../java/org/traccar/protocol/NoranProtocol.java | 3 +- .../java/org/traccar/protocol/NvsProtocol.java | 3 +- .../java/org/traccar/protocol/NyitechProtocol.java | 3 +- .../org/traccar/protocol/ObdDongleProtocol.java | 3 +- .../java/org/traccar/protocol/OigoProtocol.java | 3 +- .../java/org/traccar/protocol/OkoProtocol.java | 3 +- .../org/traccar/protocol/OmnicommProtocol.java | 3 +- .../java/org/traccar/protocol/OpenGtsProtocol.java | 3 +- .../java/org/traccar/protocol/OrbcommProtocol.java | 6 +- .../java/org/traccar/protocol/OrionProtocol.java | 3 +- .../java/org/traccar/protocol/OsmAndProtocol.java | 3 +- .../java/org/traccar/protocol/OutsafeProtocol.java | 3 +- .../org/traccar/protocol/OwnTracksProtocol.java | 3 +- .../org/traccar/protocol/PacificTrackProtocol.java | 3 +- .../org/traccar/protocol/PathAwayProtocol.java | 3 +- .../org/traccar/protocol/PiligrimProtocol.java | 3 +- .../java/org/traccar/protocol/PluginProtocol.java | 3 +- .../java/org/traccar/protocol/PolteProtocol.java | 3 +- .../java/org/traccar/protocol/PortmanProtocol.java | 3 +- .../org/traccar/protocol/PretraceProtocol.java | 3 +- .../traccar/protocol/PretraceProtocolEncoder.java | 5 +- .../java/org/traccar/protocol/PricolProtocol.java | 5 +- .../org/traccar/protocol/ProgressProtocol.java | 3 +- .../java/org/traccar/protocol/PstProtocol.java | 5 +- .../java/org/traccar/protocol/Pt215Protocol.java | 3 +- .../java/org/traccar/protocol/Pt3000Protocol.java | 3 +- .../java/org/traccar/protocol/Pt502Protocol.java | 3 +- .../org/traccar/protocol/Pt502ProtocolDecoder.java | 3 +- .../java/org/traccar/protocol/Pt60Protocol.java | 3 +- .../java/org/traccar/protocol/R12wProtocol.java | 3 +- .../org/traccar/protocol/RaceDynamicsProtocol.java | 3 +- .../java/org/traccar/protocol/RadarProtocol.java | 3 +- .../java/org/traccar/protocol/RaveonProtocol.java | 3 +- .../java/org/traccar/protocol/RecodaProtocol.java | 3 +- .../org/traccar/protocol/RetranslatorProtocol.java | 3 +- .../java/org/traccar/protocol/RitiProtocol.java | 3 +- .../org/traccar/protocol/RoboTrackProtocol.java | 3 +- .../java/org/traccar/protocol/RstProtocol.java | 3 +- .../java/org/traccar/protocol/RuptelaProtocol.java | 3 +- .../java/org/traccar/protocol/S168Protocol.java | 3 +- .../org/traccar/protocol/SabertekProtocol.java | 3 +- .../java/org/traccar/protocol/SanavProtocol.java | 5 +- .../java/org/traccar/protocol/SanulProtocol.java | 3 +- .../java/org/traccar/protocol/SatsolProtocol.java | 3 +- .../java/org/traccar/protocol/SigfoxProtocol.java | 3 +- .../java/org/traccar/protocol/SiwiProtocol.java | 3 +- .../org/traccar/protocol/SkypatrolProtocol.java | 3 +- .../org/traccar/protocol/SmartSoleProtocol.java | 3 +- .../java/org/traccar/protocol/SmokeyProtocol.java | 3 +- .../org/traccar/protocol/SolarPoweredProtocol.java | 3 +- .../java/org/traccar/protocol/SpotProtocol.java | 3 +- .../org/traccar/protocol/StarLinkProtocol.java | 3 +- .../traccar/protocol/StarLinkProtocolDecoder.java | 5 +- .../java/org/traccar/protocol/StarcomProtocol.java | 3 +- .../java/org/traccar/protocol/StartekProtocol.java | 3 +- .../java/org/traccar/protocol/StbProtocol.java | 3 +- .../java/org/traccar/protocol/Stl060Protocol.java | 3 +- .../java/org/traccar/protocol/SuntechProtocol.java | 3 +- .../traccar/protocol/SuntechProtocolDecoder.java | 11 ++- .../org/traccar/protocol/SupermateProtocol.java | 3 +- .../java/org/traccar/protocol/SviasProtocol.java | 4 +- .../org/traccar/protocol/SwiftechProtocol.java | 3 +- .../java/org/traccar/protocol/T55Protocol.java | 5 +- .../org/traccar/protocol/T55ProtocolDecoder.java | 3 +- .../java/org/traccar/protocol/T57Protocol.java | 3 +- .../java/org/traccar/protocol/T800xProtocol.java | 3 +- .../org/traccar/protocol/TaipPrefixEncoder.java | 15 ++-- .../java/org/traccar/protocol/TaipProtocol.java | 5 +- .../java/org/traccar/protocol/TechTltProtocol.java | 3 +- .../org/traccar/protocol/TechtoCruzProtocol.java | 3 +- .../java/org/traccar/protocol/TekProtocol.java | 3 +- .../java/org/traccar/protocol/TelemaxProtocol.java | 3 +- .../java/org/traccar/protocol/TelicProtocol.java | 3 +- .../org/traccar/protocol/TeltonikaProtocol.java | 5 +- .../traccar/protocol/TeltonikaProtocolDecoder.java | 3 +- .../org/traccar/protocol/TeraTrackProtocol.java | 3 +- .../org/traccar/protocol/ThinkPowerProtocol.java | 3 +- .../org/traccar/protocol/ThinkRaceProtocol.java | 3 +- .../java/org/traccar/protocol/Tk102Protocol.java | 3 +- .../java/org/traccar/protocol/Tk103Protocol.java | 5 +- .../org/traccar/protocol/Tk103ProtocolEncoder.java | 5 +- .../java/org/traccar/protocol/Tlt2hProtocol.java | 3 +- .../java/org/traccar/protocol/TlvProtocol.java | 3 +- .../java/org/traccar/protocol/TmgProtocol.java | 3 +- .../org/traccar/protocol/TopflytechProtocol.java | 3 +- .../java/org/traccar/protocol/TopinProtocol.java | 3 +- .../java/org/traccar/protocol/TotemProtocol.java | 3 +- .../java/org/traccar/protocol/Tr20Protocol.java | 5 +- .../java/org/traccar/protocol/Tr900Protocol.java | 5 +- .../org/traccar/protocol/TrackboxProtocol.java | 3 +- .../org/traccar/protocol/TrakMateProtocol.java | 3 +- .../java/org/traccar/protocol/TramigoProtocol.java | 3 +- .../java/org/traccar/protocol/TrvProtocol.java | 3 +- .../java/org/traccar/protocol/Tt8850Protocol.java | 3 +- .../java/org/traccar/protocol/TytanProtocol.java | 3 +- .../java/org/traccar/protocol/TzoneProtocol.java | 6 +- .../org/traccar/protocol/UlbotechProtocol.java | 3 +- .../java/org/traccar/protocol/UproProtocol.java | 3 +- .../java/org/traccar/protocol/UuxProtocol.java | 3 +- .../java/org/traccar/protocol/V680Protocol.java | 5 +- .../org/traccar/protocol/VisiontekProtocol.java | 3 +- .../java/org/traccar/protocol/VnetProtocol.java | 3 +- .../java/org/traccar/protocol/Vt200Protocol.java | 3 +- .../java/org/traccar/protocol/VtfmsProtocol.java | 8 +-- .../java/org/traccar/protocol/WatchProtocol.java | 3 +- .../java/org/traccar/protocol/WialonProtocol.java | 17 +++-- .../java/org/traccar/protocol/WliProtocol.java | 3 +- .../java/org/traccar/protocol/WondexProtocol.java | 8 +-- .../org/traccar/protocol/WristbandProtocol.java | 3 +- .../java/org/traccar/protocol/Xexun2Protocol.java | 3 +- .../java/org/traccar/protocol/XexunProtocol.java | 13 ++-- .../java/org/traccar/protocol/XirgoProtocol.java | 10 +-- .../java/org/traccar/protocol/Xrb28Protocol.java | 3 +- .../java/org/traccar/protocol/Xt013Protocol.java | 10 +-- .../java/org/traccar/protocol/Xt2400Protocol.java | 3 +- .../java/org/traccar/protocol/YwtProtocol.java | 3 +- src/test/java/org/traccar/BaseTest.java | 25 ++++++- .../traccar/protocol/AdmProtocolEncoderTest.java | 2 +- .../traccar/protocol/BceProtocolEncoderTest.java | 2 +- .../protocol/CastelProtocolEncoderTest.java | 2 +- .../protocol/CellocatorProtocolEncoderTest.java | 2 +- .../protocol/CityeasyProtocolEncoderTest.java | 2 +- .../protocol/EasyTrackProtocolEncoderTest.java | 4 +- .../protocol/EelinkProtocolEncoderTest.java | 19 ++++- .../traccar/protocol/EsealProtocolEncoderTest.java | 2 +- .../protocol/FifotrackProtocolEncoderTest.java | 2 +- .../protocol/GalileoProtocolEncoderTest.java | 2 +- .../protocol/GlobalSatProtocolEncoderTest.java | 8 +-- .../protocol/Gps103ProtocolEncoderTest.java | 4 +- .../traccar/protocol/Gt06ProtocolEncoderTest.java | 2 +- .../traccar/protocol/H02ProtocolEncoderTest.java | 10 ++- .../protocol/HuabaoProtocolEncoderTest.java | 2 +- .../traccar/protocol/ItsProtocolEncoderTest.java | 2 +- .../traccar/protocol/KhdProtocolEncoderTest.java | 2 +- .../protocol/MeiligaoProtocolEncoderTest.java | 2 +- .../protocol/MeitrackProtocolEncoderTest.java | 2 +- .../protocol/MiniFinderProtocolEncoderTest.java | 2 +- .../traccar/protocol/NoranProtocolEncoderTest.java | 2 +- .../protocol/PortmanProtocolEncoderTest.java | 8 +-- .../protocol/PretraceProtocolEncoderTest.java | 4 +- .../traccar/protocol/PstProtocolEncoderTest.java | 8 +-- .../traccar/protocol/Pt502ProtocolEncoderTest.java | 8 +-- .../protocol/RuptelaProtocolEncoderTest.java | 2 +- .../protocol/StartekProtocolEncoderTest.java | 4 +- .../traccar/protocol/T800xProtocolEncoderTest.java | 2 +- .../protocol/TeltonikaProtocolEncoderTest.java | 2 +- .../traccar/protocol/Tk103ProtocolEncoderTest.java | 80 +++++++++++----------- .../traccar/protocol/TopinProtocolEncoderTest.java | 2 +- .../traccar/protocol/TotemProtocolEncoderTest.java | 4 +- .../protocol/UlbotechProtocolEncoderTest.java | 4 +- .../traccar/protocol/WatchProtocolEncoderTest.java | 6 +- .../protocol/WondexProtocolEncoderTest.java | 2 +- .../traccar/protocol/XirgoProtocolEncoderTest.java | 2 +- .../traccar/protocol/Xrb28ProtocolEncoderTest.java | 8 +-- 302 files changed, 754 insertions(+), 479 deletions(-) diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 0f62c87df..9a396bd64 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -78,6 +78,10 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { init(); } + public IdentityManager getIdentityManager() { + return identityManager; + } + @Inject public void setIdentityManager(IdentityManager identityManager) { this.identityManager = identityManager; diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index 71fa61e4e..10b780fc8 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,14 @@ */ package org.traccar; +import com.google.inject.Inject; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.database.IdentityManager; import org.traccar.helper.NetworkUtil; import org.traccar.model.Command; @@ -32,21 +34,32 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter private final Protocol protocol; + private IdentityManager identityManager; + public BaseProtocolEncoder(Protocol protocol) { this.protocol = protocol; } + public IdentityManager getIdentityManager() { + return identityManager; + } + + @Inject + public void setIdentityManager(IdentityManager identityManager) { + this.identityManager = identityManager; + } + public String getProtocolName() { return protocol != null ? protocol.getName() : PROTOCOL_UNKNOWN; } protected String getUniqueId(long deviceId) { - return Context.getIdentityManager().getById(deviceId).getUniqueId(); + return identityManager.getById(deviceId).getUniqueId(); } protected void initDevicePassword(Command command, String defaultPassword) { if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { - String password = Context.getIdentityManager() + String password = identityManager .getDevicePassword(command.getDeviceId(), getProtocolName(), defaultPassword); command.set(Command.KEY_DEVICE_PASSWORD, password); } diff --git a/src/main/java/org/traccar/TrackerClient.java b/src/main/java/org/traccar/TrackerClient.java index dda02f909..12971849c 100644 --- a/src/main/java/org/traccar/TrackerClient.java +++ b/src/main/java/org/traccar/TrackerClient.java @@ -23,6 +23,7 @@ import io.netty.handler.ssl.SslHandler; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.GlobalEventExecutor; +import org.traccar.config.Config; import org.traccar.config.Keys; import javax.net.ssl.SSLContext; @@ -77,7 +78,7 @@ public abstract class TrackerClient implements TrackerConnector { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { try { - TrackerClient.this.addProtocolHandlers(pipeline); + TrackerClient.this.addProtocolHandlers(pipeline, Context.getConfig()); } catch (Exception e) { throw new RuntimeException(e); } @@ -90,7 +91,7 @@ public abstract class TrackerClient implements TrackerConnector { .handler(pipelineFactory); } - protected abstract void addProtocolHandlers(PipelineBuilder pipeline) throws Exception; + protected abstract void addProtocolHandlers(PipelineBuilder pipeline, Config config) throws Exception; public String[] getDevices() { return devices; diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index 8e2fce616..b279d3479 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -25,6 +25,7 @@ import io.netty.channel.socket.nio.NioDatagramChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.ssl.SslHandler; import io.netty.util.concurrent.GlobalEventExecutor; +import org.traccar.config.Config; import org.traccar.config.Keys; import javax.net.ssl.SSLContext; @@ -76,7 +77,7 @@ public abstract class TrackerServer implements TrackerConnector { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - TrackerServer.this.addProtocolHandlers(pipeline); + TrackerServer.this.addProtocolHandlers(pipeline, Context.getConfig()); } }; @@ -97,7 +98,7 @@ public abstract class TrackerServer implements TrackerConnector { } } - protected abstract void addProtocolHandlers(PipelineBuilder pipeline); + protected abstract void addProtocolHandlers(PipelineBuilder pipeline, Config config); public int getPort() { return port; diff --git a/src/main/java/org/traccar/protocol/AdmProtocol.java b/src/main/java/org/traccar/protocol/AdmProtocol.java index d1d81118c..8c5e2de0d 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocol.java +++ b/src/main/java/org/traccar/protocol/AdmProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class AdmProtocol extends BaseProtocol { @@ -29,7 +30,7 @@ public class AdmProtocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AdmFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new AdmProtocolEncoder(AdmProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/AisProtocol.java b/src/main/java/org/traccar/protocol/AisProtocol.java index 3b9cad7c8..5697d7f3f 100644 --- a/src/main/java/org/traccar/protocol/AisProtocol.java +++ b/src/main/java/org/traccar/protocol/AisProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AisProtocol extends BaseProtocol { public AisProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new AisProtocolDecoder(AisProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AlematicsProtocol.java b/src/main/java/org/traccar/protocol/AlematicsProtocol.java index 8da2356b9..1e68949ae 100644 --- a/src/main/java/org/traccar/protocol/AlematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/AlematicsProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AlematicsProtocol extends BaseProtocol { public AlematicsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AlematicsFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/AnytrekProtocol.java b/src/main/java/org/traccar/protocol/AnytrekProtocol.java index 9bd0c9163..8c020e64e 100644 --- a/src/main/java/org/traccar/protocol/AnytrekProtocol.java +++ b/src/main/java/org/traccar/protocol/AnytrekProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class AnytrekProtocol extends BaseProtocol { public AnytrekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 2, 0, true)); pipeline.addLast(new AnytrekProtocolDecoder(AnytrekProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ApelProtocol.java b/src/main/java/org/traccar/protocol/ApelProtocol.java index 382aa16af..0c0d6279e 100644 --- a/src/main/java/org/traccar/protocol/ApelProtocol.java +++ b/src/main/java/org/traccar/protocol/ApelProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class ApelProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class ApelProtocol extends BaseProtocol { public ApelProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); pipeline.addLast(new ApelProtocolDecoder(ApelProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AplicomProtocol.java b/src/main/java/org/traccar/protocol/AplicomProtocol.java index 2b9dbf97c..21556bd69 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocol.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AplicomProtocol extends BaseProtocol { public AplicomProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AplicomFrameDecoder()); pipeline.addLast(new AplicomProtocolDecoder(AplicomProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AppelloProtocol.java b/src/main/java/org/traccar/protocol/AppelloProtocol.java index 1ca4168e4..919c8ab62 100644 --- a/src/main/java/org/traccar/protocol/AppelloProtocol.java +++ b/src/main/java/org/traccar/protocol/AppelloProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AppelloProtocol extends BaseProtocol { public AppelloProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AquilaProtocol.java b/src/main/java/org/traccar/protocol/AquilaProtocol.java index 5ca1ec091..72161ccec 100644 --- a/src/main/java/org/traccar/protocol/AquilaProtocol.java +++ b/src/main/java/org/traccar/protocol/AquilaProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AquilaProtocol extends BaseProtocol { public AquilaProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Ardi01Protocol.java b/src/main/java/org/traccar/protocol/Ardi01Protocol.java index f7826430f..ba9dc9dfa 100644 --- a/src/main/java/org/traccar/protocol/Ardi01Protocol.java +++ b/src/main/java/org/traccar/protocol/Ardi01Protocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Ardi01Protocol extends BaseProtocol { public Ardi01Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ArknavProtocol.java b/src/main/java/org/traccar/protocol/ArknavProtocol.java index 3b485e4a5..76db3781c 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocol.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ArknavProtocol extends BaseProtocol { public ArknavProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java index a29bc1ad3..55d2c58f9 100644 --- a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java +++ b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ArknavX8Protocol extends BaseProtocol { public ArknavX8Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java index 5f36012af..70e70c89b 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocol.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ArmoliProtocol extends BaseProtocol { public ArmoliProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";;", ";\r", ";")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocol.java b/src/main/java/org/traccar/protocol/ArnaviProtocol.java index aecb42c8c..18af4e9be 100644 --- a/src/main/java/org/traccar/protocol/ArnaviProtocol.java +++ b/src/main/java/org/traccar/protocol/ArnaviProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ArnaviProtocol extends BaseProtocol { public ArnaviProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new ArnaviFrameDecoder()); pipeline.addLast(new ArnaviProtocolDecoder(ArnaviProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AstraProtocol.java b/src/main/java/org/traccar/protocol/AstraProtocol.java index 12b0dfb68..c79c7f6fc 100644 --- a/src/main/java/org/traccar/protocol/AstraProtocol.java +++ b/src/main/java/org/traccar/protocol/AstraProtocol.java @@ -19,20 +19,21 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AstraProtocol extends BaseProtocol { public AstraProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -3, 0)); pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/At2000Protocol.java b/src/main/java/org/traccar/protocol/At2000Protocol.java index 5894f3eab..44bb11b94 100644 --- a/src/main/java/org/traccar/protocol/At2000Protocol.java +++ b/src/main/java/org/traccar/protocol/At2000Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class At2000Protocol extends BaseProtocol { public At2000Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new At2000FrameDecoder()); pipeline.addLast(new At2000ProtocolDecoder(At2000Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AtrackProtocol.java b/src/main/java/org/traccar/protocol/AtrackProtocol.java index 429708b26..65cd5194e 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class AtrackProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class AtrackProtocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AtrackFrameDecoder()); pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this)); pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); @@ -35,7 +36,7 @@ public class AtrackProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this)); pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AuroProtocol.java b/src/main/java/org/traccar/protocol/AuroProtocol.java index b8ebdaa75..f05b3f71c 100644 --- a/src/main/java/org/traccar/protocol/AuroProtocol.java +++ b/src/main/java/org/traccar/protocol/AuroProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AuroProtocol extends BaseProtocol { public AuroProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocol.java b/src/main/java/org/traccar/protocol/AustinNbProtocol.java index 32bfc0aae..18a1c6c6a 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocol.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AustinNbProtocol extends BaseProtocol { public AustinNbProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new AustinNbProtocolDecoder(AustinNbProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/AutoFonProtocol.java b/src/main/java/org/traccar/protocol/AutoFonProtocol.java index 08b5edc7d..36d384c94 100644 --- a/src/main/java/org/traccar/protocol/AutoFonProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoFonProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AutoFonProtocol extends BaseProtocol { public AutoFonProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AutoFonFrameDecoder()); pipeline.addLast(new AutoFonProtocolDecoder(AutoFonProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java index c6dbb681e..c9d997163 100644 --- a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AutoGradeProtocol extends BaseProtocol { public AutoGradeProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java index 6aa7558bf..99a59fad7 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class AutoTrackProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class AutoTrackProtocol extends BaseProtocol { public AutoTrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 5, 2, 2, 0, true)); pipeline.addLast(new AutoTrackProtocolDecoder(AutoTrackProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/AvemaProtocol.java b/src/main/java/org/traccar/protocol/AvemaProtocol.java index dbfab4dea..69d2cbfa7 100644 --- a/src/main/java/org/traccar/protocol/AvemaProtocol.java +++ b/src/main/java/org/traccar/protocol/AvemaProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class AvemaProtocol extends BaseProtocol { public AvemaProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Avl301Protocol.java b/src/main/java/org/traccar/protocol/Avl301Protocol.java index 71fc7cb26..bae4de7d0 100644 --- a/src/main/java/org/traccar/protocol/Avl301Protocol.java +++ b/src/main/java/org/traccar/protocol/Avl301Protocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Avl301Protocol extends BaseProtocol { public Avl301Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, -3, 0)); pipeline.addLast(new Avl301ProtocolDecoder(Avl301Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/B2316Protocol.java b/src/main/java/org/traccar/protocol/B2316Protocol.java index 7f08870ce..5b9d297f9 100644 --- a/src/main/java/org/traccar/protocol/B2316Protocol.java +++ b/src/main/java/org/traccar/protocol/B2316Protocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class B2316Protocol extends BaseProtocol { public B2316Protocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new B2316ProtocolDecoder(B2316Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/BceProtocol.java b/src/main/java/org/traccar/protocol/BceProtocol.java index c5e1dd04c..2d92894aa 100644 --- a/src/main/java/org/traccar/protocol/BceProtocol.java +++ b/src/main/java/org/traccar/protocol/BceProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class BceProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class BceProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new BceFrameDecoder()); pipeline.addLast(new BceProtocolEncoder(BceProtocol.this)); pipeline.addLast(new BceProtocolDecoder(BceProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java index 617a24d7a..e464b18d1 100644 --- a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java +++ b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java @@ -19,13 +19,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class BlackKiteProtocol extends BaseProtocol { public BlackKiteProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GalileoFrameDecoder()); pipeline.addLast(new BlackKiteProtocolDecoder(BlackKiteProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/BlueProtocol.java b/src/main/java/org/traccar/protocol/BlueProtocol.java index d5dc5c421..9d42e386e 100644 --- a/src/main/java/org/traccar/protocol/BlueProtocol.java +++ b/src/main/java/org/traccar/protocol/BlueProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class BlueProtocol extends BaseProtocol { public BlueProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -2, 0)); pipeline.addLast(new BlueProtocolDecoder(BlueProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/BoxProtocol.java b/src/main/java/org/traccar/protocol/BoxProtocol.java index dfea15938..72a13c94a 100644 --- a/src/main/java/org/traccar/protocol/BoxProtocol.java +++ b/src/main/java/org/traccar/protocol/BoxProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class BoxProtocol extends BaseProtocol { public BoxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/C2stekProtocol.java b/src/main/java/org/traccar/protocol/C2stekProtocol.java index 804621fd3..da490aedc 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocol.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class C2stekProtocol extends BaseProtocol { public C2stekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, false, "$AP")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocol.java b/src/main/java/org/traccar/protocol/CalAmpProtocol.java index 232e72a8c..056f23d01 100644 --- a/src/main/java/org/traccar/protocol/CalAmpProtocol.java +++ b/src/main/java/org/traccar/protocol/CalAmpProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CalAmpProtocol extends BaseProtocol { public CalAmpProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CalAmpProtocolDecoder(CalAmpProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/CarTrackProtocol.java b/src/main/java/org/traccar/protocol/CarTrackProtocol.java index e340fba25..133fd8036 100644 --- a/src/main/java/org/traccar/protocol/CarTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/CarTrackProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CarTrackProtocol extends BaseProtocol { public CarTrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/CarcellProtocol.java b/src/main/java/org/traccar/protocol/CarcellProtocol.java index f08ab3bd9..489b1d1de 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocol.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class CarcellProtocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class CarcellProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CarscopProtocol.java b/src/main/java/org/traccar/protocol/CarscopProtocol.java index 2c754a97f..d4c246c59 100644 --- a/src/main/java/org/traccar/protocol/CarscopProtocol.java +++ b/src/main/java/org/traccar/protocol/CarscopProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CarscopProtocol extends BaseProtocol { public CarscopProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '^')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CastelProtocol.java b/src/main/java/org/traccar/protocol/CastelProtocol.java index 44c52d68f..ee5432753 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocol.java +++ b/src/main/java/org/traccar/protocol/CastelProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; import java.nio.ByteOrder; @@ -30,7 +31,7 @@ public class CastelProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this)); pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); @@ -38,7 +39,7 @@ public class CastelProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this)); pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java index dc694da28..0fb4bf8b4 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java @@ -18,10 +18,9 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import org.traccar.Protocol; import java.nio.charset.StandardCharsets; @@ -34,7 +33,7 @@ public class CastelProtocolEncoder extends BaseProtocolEncoder { private ByteBuf encodeContent(long deviceId, short type, ByteBuf content) { ByteBuf buf = Unpooled.buffer(0); - String uniqueId = Context.getIdentityManager().getById(deviceId).getUniqueId(); + String uniqueId = getIdentityManager().getById(deviceId).getUniqueId(); buf.writeByte('@'); buf.writeByte('@'); diff --git a/src/main/java/org/traccar/protocol/CautelaProtocol.java b/src/main/java/org/traccar/protocol/CautelaProtocol.java index 452bdf8d4..13f3770b7 100644 --- a/src/main/java/org/traccar/protocol/CautelaProtocol.java +++ b/src/main/java/org/traccar/protocol/CautelaProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CautelaProtocol extends BaseProtocol { public CautelaProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocol.java b/src/main/java/org/traccar/protocol/CellocatorProtocol.java index d910877cf..6532848ac 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocol.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class CellocatorProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class CellocatorProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CellocatorFrameDecoder()); pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this)); pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); @@ -35,7 +36,7 @@ public class CellocatorProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this)); pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/CguardProtocol.java b/src/main/java/org/traccar/protocol/CguardProtocol.java index 9157ca35c..ad5539fbd 100644 --- a/src/main/java/org/traccar/protocol/CguardProtocol.java +++ b/src/main/java/org/traccar/protocol/CguardProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CguardProtocol extends BaseProtocol { public CguardProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocol.java b/src/main/java/org/traccar/protocol/CityeasyProtocol.java index 8ab4ce93a..28337bde9 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocol.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class CityeasyProtocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class CityeasyProtocol extends BaseProtocol { Command.TYPE_SET_TIMEZONE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); pipeline.addLast(new CityeasyProtocolEncoder(CityeasyProtocol.this)); pipeline.addLast(new CityeasyProtocolDecoder(CityeasyProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/ContinentalProtocol.java b/src/main/java/org/traccar/protocol/ContinentalProtocol.java index bc7928fba..bbff3bda6 100644 --- a/src/main/java/org/traccar/protocol/ContinentalProtocol.java +++ b/src/main/java/org/traccar/protocol/ContinentalProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ContinentalProtocol extends BaseProtocol { public ContinentalProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); pipeline.addLast(new ContinentalProtocolDecoder(ContinentalProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/CradlepointProtocol.java b/src/main/java/org/traccar/protocol/CradlepointProtocol.java index 4a09e0311..7d2270743 100644 --- a/src/main/java/org/traccar/protocol/CradlepointProtocol.java +++ b/src/main/java/org/traccar/protocol/CradlepointProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class CradlepointProtocol extends BaseProtocol { public CradlepointProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/DingtekProtocol.java b/src/main/java/org/traccar/protocol/DingtekProtocol.java index cf2a6c0f5..7864d24df 100644 --- a/src/main/java/org/traccar/protocol/DingtekProtocol.java +++ b/src/main/java/org/traccar/protocol/DingtekProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class DingtekProtocol extends BaseProtocol { public DingtekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new DingtekFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/DishaProtocol.java b/src/main/java/org/traccar/protocol/DishaProtocol.java index 38f49cc05..c81c88c7c 100644 --- a/src/main/java/org/traccar/protocol/DishaProtocol.java +++ b/src/main/java/org/traccar/protocol/DishaProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class DishaProtocol extends BaseProtocol { public DishaProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java index 34568128f..107ec430c 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class DmtHttpProtocol extends BaseProtocol { public DmtHttpProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/DmtProtocol.java b/src/main/java/org/traccar/protocol/DmtProtocol.java index 78a5243c0..d84099fac 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class DmtProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class DmtProtocol extends BaseProtocol { public DmtProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); pipeline.addLast(new DmtProtocolDecoder(DmtProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/DolphinProtocol.java b/src/main/java/org/traccar/protocol/DolphinProtocol.java index 07c827e18..1e67de8b2 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocol.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class DolphinProtocol extends BaseProtocol { public DolphinProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 4096, 20, 4, 4, 0, true)); pipeline.addLast(new DolphinProtocolDecoder(DolphinProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Dsf22Protocol.java b/src/main/java/org/traccar/protocol/Dsf22Protocol.java index bffc3e419..fcc7e7d55 100644 --- a/src/main/java/org/traccar/protocol/Dsf22Protocol.java +++ b/src/main/java/org/traccar/protocol/Dsf22Protocol.java @@ -18,20 +18,21 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Dsf22Protocol extends BaseProtocol { public Dsf22Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Dsf22FrameDecoder()); pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/DualcamProtocol.java b/src/main/java/org/traccar/protocol/DualcamProtocol.java index 04c4f2bd1..ba1dc0e4b 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocol.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class DualcamProtocol extends BaseProtocol { public DualcamProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new DualcamFrameDecoder()); pipeline.addLast(new DualcamProtocolDecoder(DualcamProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/DwayProtocol.java b/src/main/java/org/traccar/protocol/DwayProtocol.java index 05fd8b6e7..a729d6401 100644 --- a/src/main/java/org/traccar/protocol/DwayProtocol.java +++ b/src/main/java/org/traccar/protocol/DwayProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class DwayProtocol extends BaseProtocol { public DwayProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java index 972b36077..0c1fec7e8 100644 --- a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class EasyTrackProtocol extends BaseProtocol { @@ -33,7 +34,7 @@ public class EasyTrackProtocol extends BaseProtocol { Command.TYPE_ALARM_DISARM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#\r\n", "#", "\r\n")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/EelinkProtocol.java b/src/main/java/org/traccar/protocol/EelinkProtocol.java index 8a055d643..654468ea0 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocol.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class EelinkProtocol extends BaseProtocol { @@ -32,7 +33,7 @@ public class EelinkProtocol extends BaseProtocol { Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, false)); pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); @@ -40,7 +41,7 @@ public class EelinkProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, true)); pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/EgtsProtocol.java b/src/main/java/org/traccar/protocol/EgtsProtocol.java index 5d4638f37..fb17e41ae 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocol.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class EgtsProtocol extends BaseProtocol { public EgtsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EgtsFrameDecoder()); pipeline.addLast(new EgtsProtocolDecoder(EgtsProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/EnforaProtocol.java b/src/main/java/org/traccar/protocol/EnforaProtocol.java index e462ab322..5386787ea 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocol.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class EnforaProtocol extends BaseProtocol { @@ -30,7 +31,7 @@ public class EnforaProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, -2, 2)); pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this)); pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); @@ -38,7 +39,7 @@ public class EnforaProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this)); pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/EnnfuProtocol.java b/src/main/java/org/traccar/protocol/EnnfuProtocol.java index 7ef94d83f..e72ff29ba 100644 --- a/src/main/java/org/traccar/protocol/EnnfuProtocol.java +++ b/src/main/java/org/traccar/protocol/EnnfuProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class EnnfuProtocol extends BaseProtocol { public EnnfuProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocol.java b/src/main/java/org/traccar/protocol/EnvotechProtocol.java index 8eb71ee6b..8ccf1776f 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocol.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class EnvotechProtocol extends BaseProtocol { public EnvotechProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/EsealProtocol.java b/src/main/java/org/traccar/protocol/EsealProtocol.java index fc1d342e1..e63e7ee5f 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocol.java +++ b/src/main/java/org/traccar/protocol/EsealProtocol.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class EsealProtocol extends BaseProtocol { @@ -32,7 +33,7 @@ public class EsealProtocol extends BaseProtocol { Command.TYPE_ALARM_DISARM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/EskyProtocol.java b/src/main/java/org/traccar/protocol/EskyProtocol.java index fb047c207..dd81f4954 100644 --- a/src/main/java/org/traccar/protocol/EskyProtocol.java +++ b/src/main/java/org/traccar/protocol/EskyProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class EskyProtocol extends BaseProtocol { public EskyProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EskyFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -35,7 +36,7 @@ public class EskyProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new EskyProtocolDecoder(EskyProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java index 692fd4e99..4da56a8eb 100644 --- a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java +++ b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ExtremTracProtocol extends BaseProtocol { public ExtremTracProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocol.java b/src/main/java/org/traccar/protocol/FifotrackProtocol.java index 4a0a12ed3..7de8f3f62 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class FifotrackProtocol extends BaseProtocol { @@ -29,7 +30,7 @@ public class FifotrackProtocol extends BaseProtocol { Command.TYPE_REQUEST_PHOTO); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FifotrackFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new FifotrackProtocolEncoder(FifotrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/FlespiProtocol.java b/src/main/java/org/traccar/protocol/FlespiProtocol.java index 05b105f93..874be7f68 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FlespiProtocol extends BaseProtocol { public FlespiProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder(4096, 8192, 128 * 1024)); pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE)); diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java index 7f4154f71..87ae8e274 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -20,6 +20,7 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.charset.StandardCharsets; @@ -28,7 +29,7 @@ public class FlexApiProtocol extends BaseProtocol { public FlexApiProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(5120)); pipeline.addLast(new StringDecoder(StandardCharsets.US_ASCII)); pipeline.addLast(new FlexApiProtocolDecoder(FlexApiProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/FlexCommProtocol.java b/src/main/java/org/traccar/protocol/FlexCommProtocol.java index 9343ebeb8..6e6e59f24 100644 --- a/src/main/java/org/traccar/protocol/FlexCommProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexCommProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FlexCommProtocol extends BaseProtocol { public FlexCommProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(2 + 2 + 101 + 5)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java index 0cd55343a..0d6437d83 100644 --- a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FlexibleReportProtocol extends BaseProtocol { public FlexibleReportProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FlexibleReportProtocolDecoder(FlexibleReportProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/FlextrackProtocol.java b/src/main/java/org/traccar/protocol/FlextrackProtocol.java index ddd1d58f0..f80460477 100644 --- a/src/main/java/org/traccar/protocol/FlextrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FlextrackProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FlextrackProtocol extends BaseProtocol { public FlextrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/FoxProtocol.java b/src/main/java/org/traccar/protocol/FoxProtocol.java index 9bac773b5..a91c2b2c5 100644 --- a/src/main/java/org/traccar/protocol/FoxProtocol.java +++ b/src/main/java/org/traccar/protocol/FoxProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FoxProtocol extends BaseProtocol { public FoxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/FreedomProtocol.java b/src/main/java/org/traccar/protocol/FreedomProtocol.java index bc6b92d5f..6a7a2d72e 100644 --- a/src/main/java/org/traccar/protocol/FreedomProtocol.java +++ b/src/main/java/org/traccar/protocol/FreedomProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FreedomProtocol extends BaseProtocol { public FreedomProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocol.java b/src/main/java/org/traccar/protocol/FreematicsProtocol.java index 999b075a1..0220b2030 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FreematicsProtocol extends BaseProtocol { public FreematicsProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new FreematicsProtocolDecoder(FreematicsProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/FutureWayProtocol.java b/src/main/java/org/traccar/protocol/FutureWayProtocol.java index 73b53ee12..7d2160345 100644 --- a/src/main/java/org/traccar/protocol/FutureWayProtocol.java +++ b/src/main/java/org/traccar/protocol/FutureWayProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class FutureWayProtocol extends BaseProtocol { public FutureWayProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FutureWayFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/GalileoProtocol.java b/src/main/java/org/traccar/protocol/GalileoProtocol.java index a1570c9b0..a3cda7fa1 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocol.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class GalileoProtocol extends BaseProtocol { @@ -28,7 +29,7 @@ public class GalileoProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GalileoFrameDecoder()); 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 eb553c5a9..4c6d915d5 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; 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; @@ -239,8 +238,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodePositions( - Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private Object decodePositions(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { int length = (buf.readUnsignedShortLE() & 0x7fff) + 3; @@ -322,7 +320,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); + String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/main/java/org/traccar/protocol/GatorProtocol.java b/src/main/java/org/traccar/protocol/GatorProtocol.java index ca81caefb..a123b36ec 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocol.java +++ b/src/main/java/org/traccar/protocol/GatorProtocol.java @@ -19,20 +19,21 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GatorProtocol extends BaseProtocol { public GatorProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/GenxProtocol.java b/src/main/java/org/traccar/protocol/GenxProtocol.java index c87ba946a..5bd89c512 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocol.java +++ b/src/main/java/org/traccar/protocol/GenxProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GenxProtocol extends BaseProtocol { public GenxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new GenxProtocolDecoder(GenxProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gl100Protocol.java b/src/main/java/org/traccar/protocol/Gl100Protocol.java index 063e606db..91b039467 100644 --- a/src/main/java/org/traccar/protocol/Gl100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl100Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Gl100Protocol extends BaseProtocol { public Gl100Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -36,7 +37,7 @@ public class Gl100Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Gl100ProtocolDecoder(Gl100Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gl200Protocol.java b/src/main/java/org/traccar/protocol/Gl200Protocol.java index e2d0c6d2a..4d74e3116 100644 --- a/src/main/java/org/traccar/protocol/Gl200Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl200Protocol.java @@ -15,13 +15,13 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; -import io.netty.handler.codec.string.StringEncoder; - public class Gl200Protocol extends BaseProtocol { public Gl200Protocol() { @@ -33,7 +33,7 @@ public class Gl200Protocol extends BaseProtocol { Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gl200FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Gl200ProtocolEncoder(Gl200Protocol.this)); @@ -42,7 +42,7 @@ public class Gl200Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new Gl200ProtocolEncoder(Gl200Protocol.this)); pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java index e86b5dc30..d5e3a483b 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class GlobalSatProtocol extends BaseProtocol { @@ -32,7 +33,7 @@ public class GlobalSatProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "!\r\n", "!")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java index 84cd5565b..e829ff37e 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GlobalstarProtocol extends BaseProtocol { public GlobalstarProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/GnxProtocol.java b/src/main/java/org/traccar/protocol/GnxProtocol.java index 3576bf805..c51888336 100644 --- a/src/main/java/org/traccar/protocol/GnxProtocol.java +++ b/src/main/java/org/traccar/protocol/GnxProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GnxProtocol extends BaseProtocol { public GnxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\n\r")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocol.java b/src/main/java/org/traccar/protocol/GoSafeProtocol.java index aaaffac97..35216436a 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocol.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GoSafeProtocol extends BaseProtocol { public GoSafeProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -36,7 +37,7 @@ public class GoSafeProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new GoSafeProtocolDecoder(GoSafeProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GotopProtocol.java b/src/main/java/org/traccar/protocol/GotopProtocol.java index 07fe02248..e2fe4ff93 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocol.java +++ b/src/main/java/org/traccar/protocol/GotopProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GotopProtocol extends BaseProtocol { public GotopProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Gps056Protocol.java b/src/main/java/org/traccar/protocol/Gps056Protocol.java index b6ab10a19..fa7e5c12e 100644 --- a/src/main/java/org/traccar/protocol/Gps056Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps056Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Gps056Protocol extends BaseProtocol { public Gps056Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gps056FrameDecoder()); pipeline.addLast(new Gps056ProtocolDecoder(Gps056Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Gps103Protocol.java b/src/main/java/org/traccar/protocol/Gps103Protocol.java index 5356387ce..bf0b01526 100644 --- a/src/main/java/org/traccar/protocol/Gps103Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps103Protocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class Gps103Protocol extends BaseProtocol { @@ -38,7 +39,7 @@ public class Gps103Protocol extends BaseProtocol { Command.TYPE_REQUEST_PHOTO); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(2048, false, "\r\n", "\n", ";", "*")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -48,7 +49,7 @@ public class Gps103Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Gps103ProtocolEncoder(Gps103Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/GpsGateProtocol.java b/src/main/java/org/traccar/protocol/GpsGateProtocol.java index a131b6f48..51dbae7e3 100644 --- a/src/main/java/org/traccar/protocol/GpsGateProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsGateProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GpsGateProtocol extends BaseProtocol { public GpsGateProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\0", "\n", "\r\n")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java index ad23ece48..3a0c1aeb9 100644 --- a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GpsMarkerProtocol extends BaseProtocol { public GpsMarkerProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java index ce6cc5929..68241958b 100644 --- a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class GpsmtaProtocol extends BaseProtocol { public GpsmtaProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new GpsmtaProtocolDecoder(GpsmtaProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GranitProtocol.java b/src/main/java/org/traccar/protocol/GranitProtocol.java index 244c3977b..58c3d1ba4 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocol.java +++ b/src/main/java/org/traccar/protocol/GranitProtocol.java @@ -19,6 +19,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class GranitProtocol extends BaseProtocol { @@ -34,7 +35,7 @@ public class GranitProtocol extends BaseProtocol { Command.TYPE_POSITION_PERIODIC); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GranitFrameDecoder()); pipeline.addLast(new GranitProtocolEncoder(GranitProtocol.this)); pipeline.addLast(new GranitProtocolDecoder(GranitProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gs100Protocol.java b/src/main/java/org/traccar/protocol/Gs100Protocol.java index a701815d0..bd7c21b57 100644 --- a/src/main/java/org/traccar/protocol/Gs100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gs100Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Gs100Protocol extends BaseProtocol { public Gs100Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gs100ProtocolDecoder(Gs100Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/Gt02Protocol.java b/src/main/java/org/traccar/protocol/Gt02Protocol.java index f412ee720..c57de2fd6 100644 --- a/src/main/java/org/traccar/protocol/Gt02Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt02Protocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Gt02Protocol extends BaseProtocol { public Gt02Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, 2, 0)); pipeline.addLast(new Gt02ProtocolDecoder(Gt02Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Gt06Protocol.java b/src/main/java/org/traccar/protocol/Gt06Protocol.java index 9ec8de098..48eb77c0c 100644 --- a/src/main/java/org/traccar/protocol/Gt06Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt06Protocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class Gt06Protocol extends BaseProtocol { @@ -29,7 +30,7 @@ public class Gt06Protocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gt06FrameDecoder()); 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 832645374..22f38a497 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; 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; @@ -1027,7 +1026,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (photo.writableBytes() > 0) { sendPhotoRequest(channel, pictureId); } else { - Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); + Device device = getIdentityManager().getById(deviceSession.getDeviceId()); position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); photos.remove(pictureId).release(); } @@ -1263,7 +1262,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, new Date(timestamp)); - Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); + Device device = getIdentityManager().getById(deviceSession.getDeviceId()); position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); photos.remove(mediaId).release(); } diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index 9115ba10f..3ed828fc7 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -18,10 +18,9 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import org.traccar.Protocol; import java.nio.charset.StandardCharsets; @@ -33,7 +32,7 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { private ByteBuf encodeContent(long deviceId, String content) { - boolean language = Context.getIdentityManager() + boolean language = getIdentityManager() .lookupAttributeBoolean(deviceId, getProtocolName() + ".language", false, false, true); ByteBuf buf = Unpooled.buffer(); @@ -66,10 +65,10 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( + boolean alternative = getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); - String password = Context.getIdentityManager() + String password = getIdentityManager() .getDevicePassword(command.getDeviceId(), getProtocolName(), "123456"); switch (command.getType()) { diff --git a/src/main/java/org/traccar/protocol/Gt30Protocol.java b/src/main/java/org/traccar/protocol/Gt30Protocol.java index aa4ad20b1..da401acd1 100644 --- a/src/main/java/org/traccar/protocol/Gt30Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt30Protocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Gt30Protocol extends BaseProtocol { public Gt30Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/H02Protocol.java b/src/main/java/org/traccar/protocol/H02Protocol.java index a5246abc6..d35333171 100644 --- a/src/main/java/org/traccar/protocol/H02Protocol.java +++ b/src/main/java/org/traccar/protocol/H02Protocol.java @@ -17,9 +17,9 @@ package org.traccar.protocol; import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; @@ -35,8 +35,8 @@ public class H02Protocol extends BaseProtocol { ); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - int messageLength = Context.getConfig().getInteger(Keys.PROTOCOL_MESSAGE_LENGTH.withPrefix(getName())); + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + int messageLength = config.getInteger(Keys.PROTOCOL_MESSAGE_LENGTH.withPrefix(getName())); pipeline.addLast(new H02FrameDecoder(messageLength)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new H02ProtocolEncoder(H02Protocol.this)); @@ -45,7 +45,7 @@ public class H02Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new H02ProtocolEncoder(H02Protocol.this)); pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java index 8f1a8c042..7fca0f93e 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java @@ -16,10 +16,9 @@ */ package org.traccar.protocol; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; -import org.traccar.Protocol; import java.util.Date; @@ -59,7 +58,7 @@ public class H02ProtocolEncoder extends StringProtocolEncoder { return formatCommand(time, uniqueId, "S20", "1", "0"); case Command.TYPE_POSITION_PERIODIC: String frequency = command.getAttributes().get(Command.KEY_FREQUENCY).toString(); - if (Context.getIdentityManager().lookupAttributeBoolean( + if (getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true)) { return formatCommand(time, uniqueId, "D1", frequency); } else { diff --git a/src/main/java/org/traccar/protocol/HaicomProtocol.java b/src/main/java/org/traccar/protocol/HaicomProtocol.java index 6e5760bd4..c03c3c0b3 100644 --- a/src/main/java/org/traccar/protocol/HaicomProtocol.java +++ b/src/main/java/org/traccar/protocol/HaicomProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class HaicomProtocol extends BaseProtocol { public HaicomProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '*')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/HomtecsProtocol.java b/src/main/java/org/traccar/protocol/HomtecsProtocol.java index 34dbf0f51..85e4012a2 100644 --- a/src/main/java/org/traccar/protocol/HomtecsProtocol.java +++ b/src/main/java/org/traccar/protocol/HomtecsProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class HomtecsProtocol extends BaseProtocol { public HomtecsProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new HomtecsProtocolDecoder(HomtecsProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/HoopoProtocol.java b/src/main/java/org/traccar/protocol/HoopoProtocol.java index 387b967d3..8795ed727 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocol.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class HoopoProtocol extends BaseProtocol { public HoopoProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocol.java b/src/main/java/org/traccar/protocol/HuaShengProtocol.java index 103f2d501..bf3b2052a 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocol.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class HuaShengProtocol extends BaseProtocol { public HuaShengProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuaShengFrameDecoder()); pipeline.addLast(new HuaShengProtocolDecoder(HuaShengProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocol.java b/src/main/java/org/traccar/protocol/HuabaoProtocol.java index 791672b85..0e1ab0b02 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocol.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class HuabaoProtocol extends BaseProtocol { @@ -28,7 +29,7 @@ public class HuabaoProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuabaoFrameDecoder()); pipeline.addLast(new HuabaoProtocolEncoder(HuabaoProtocol.this)); pipeline.addLast(new HuabaoProtocolDecoder(HuabaoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java index 55c1e0c3b..82cf03b51 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java @@ -18,10 +18,9 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.model.Command; -import org.traccar.Protocol; import java.text.SimpleDateFormat; import java.util.Date; @@ -35,7 +34,7 @@ public class HuabaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( + boolean alternative = getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); ByteBuf id = Unpooled.wrappedBuffer( diff --git a/src/main/java/org/traccar/protocol/HunterProProtocol.java b/src/main/java/org/traccar/protocol/HunterProProtocol.java index 9f6424a57..e0f8bab28 100644 --- a/src/main/java/org/traccar/protocol/HunterProProtocol.java +++ b/src/main/java/org/traccar/protocol/HunterProProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class HunterProProtocol extends BaseProtocol { public HunterProProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/IdplProtocol.java b/src/main/java/org/traccar/protocol/IdplProtocol.java index 418178756..5dda72c64 100644 --- a/src/main/java/org/traccar/protocol/IdplProtocol.java +++ b/src/main/java/org/traccar/protocol/IdplProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class IdplProtocol extends BaseProtocol { public IdplProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/IntellitracProtocol.java b/src/main/java/org/traccar/protocol/IntellitracProtocol.java index 3abf40da7..c39be0fd0 100644 --- a/src/main/java/org/traccar/protocol/IntellitracProtocol.java +++ b/src/main/java/org/traccar/protocol/IntellitracProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class IntellitracProtocol extends BaseProtocol { public IntellitracProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new IntellitracFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/IotmProtocol.java b/src/main/java/org/traccar/protocol/IotmProtocol.java index f202d9b9d..b59d0ff3d 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocol.java +++ b/src/main/java/org/traccar/protocol/IotmProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.mqtt.MqttEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class IotmProtocol extends BaseProtocol { public IotmProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(MqttEncoder.INSTANCE); pipeline.addLast(new MqttDecoder()); pipeline.addLast(new IotmProtocolDecoder(IotmProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/ItsProtocol.java b/src/main/java/org/traccar/protocol/ItsProtocol.java index 45df3da11..76097b20f 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocol.java +++ b/src/main/java/org/traccar/protocol/ItsProtocol.java @@ -20,6 +20,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class ItsProtocol extends BaseProtocol { @@ -30,7 +31,7 @@ public class ItsProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new ItsFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Ivt401Protocol.java b/src/main/java/org/traccar/protocol/Ivt401Protocol.java index fb44e4fe9..2ef3ea2bf 100644 --- a/src/main/java/org/traccar/protocol/Ivt401Protocol.java +++ b/src/main/java/org/traccar/protocol/Ivt401Protocol.java @@ -20,13 +20,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Ivt401Protocol extends BaseProtocol { public Ivt401Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Ivt401ProtocolDecoder(Ivt401Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/JidoProtocol.java b/src/main/java/org/traccar/protocol/JidoProtocol.java index 2a2e71dbe..1040b45b9 100644 --- a/src/main/java/org/traccar/protocol/JidoProtocol.java +++ b/src/main/java/org/traccar/protocol/JidoProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class JidoProtocol extends BaseProtocol { public JidoProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java index fe5b2480d..c27dde8f1 100644 --- a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java +++ b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class JpKorjarProtocol extends BaseProtocol { public JpKorjarProtocol() { addServer(new TrackerServer(false, this.getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JpKorjarFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new JpKorjarProtocolDecoder(JpKorjarProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Jt600Protocol.java b/src/main/java/org/traccar/protocol/Jt600Protocol.java index 37c82f741..7bc88de21 100644 --- a/src/main/java/org/traccar/protocol/Jt600Protocol.java +++ b/src/main/java/org/traccar/protocol/Jt600Protocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class Jt600Protocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class Jt600Protocol extends BaseProtocol { Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Jt600FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Jt600ProtocolEncoder(Jt600Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/KenjiProtocol.java b/src/main/java/org/traccar/protocol/KenjiProtocol.java index 90c0c511c..91d5cf5b6 100644 --- a/src/main/java/org/traccar/protocol/KenjiProtocol.java +++ b/src/main/java/org/traccar/protocol/KenjiProtocol.java @@ -22,13 +22,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class KenjiProtocol extends BaseProtocol { public KenjiProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/KhdProtocol.java b/src/main/java/org/traccar/protocol/KhdProtocol.java index 60a2aea7f..835d4ea0b 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocol.java +++ b/src/main/java/org/traccar/protocol/KhdProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class KhdProtocol extends BaseProtocol { @@ -35,7 +36,7 @@ public class KhdProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(512, 3, 2)); pipeline.addLast(new KhdProtocolEncoder(KhdProtocol.this)); pipeline.addLast(new KhdProtocolDecoder(KhdProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/L100Protocol.java b/src/main/java/org/traccar/protocol/L100Protocol.java index 942029307..44770c316 100644 --- a/src/main/java/org/traccar/protocol/L100Protocol.java +++ b/src/main/java/org/traccar/protocol/L100Protocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class L100Protocol extends BaseProtocol { public L100Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new L100FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/LacakProtocol.java b/src/main/java/org/traccar/protocol/LacakProtocol.java index 0a0499ad7..a22ba609d 100644 --- a/src/main/java/org/traccar/protocol/LacakProtocol.java +++ b/src/main/java/org/traccar/protocol/LacakProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class LacakProtocol extends BaseProtocol { public LacakProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocol.java b/src/main/java/org/traccar/protocol/LaipacProtocol.java index 1d561dbd2..973dcac06 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocol.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocol.java @@ -18,10 +18,11 @@ 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; +import org.traccar.config.Config; +import org.traccar.model.Command; public class LaipacProtocol extends BaseProtocol { @@ -34,7 +35,7 @@ public class LaipacProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 45890e9a2..d8554dc13 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -17,7 +17,6 @@ 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; @@ -253,7 +252,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { sendAcknowledge(status, event, checksum, channel, remoteAddress); - String devicePassword = Context.getIdentityManager() + String devicePassword = getIdentityManager() .getDevicePassword(deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); sendEventResponse(event, devicePassword, channel, remoteAddress); } diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java index 05f63a2d7..b121da2df 100644 --- a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java @@ -22,13 +22,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class LeafSpyProtocol extends BaseProtocol { public LeafSpyProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/M2cProtocol.java b/src/main/java/org/traccar/protocol/M2cProtocol.java index 9de8526c3..696823460 100644 --- a/src/main/java/org/traccar/protocol/M2cProtocol.java +++ b/src/main/java/org/traccar/protocol/M2cProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class M2cProtocol extends BaseProtocol { public M2cProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, ']')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/M2mProtocol.java b/src/main/java/org/traccar/protocol/M2mProtocol.java index dda328a59..e21b61b91 100644 --- a/src/main/java/org/traccar/protocol/M2mProtocol.java +++ b/src/main/java/org/traccar/protocol/M2mProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.FixedLengthFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class M2mProtocol extends BaseProtocol { public M2mProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(23)); pipeline.addLast(new M2mProtocolDecoder(M2mProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/MaestroProtocol.java b/src/main/java/org/traccar/protocol/MaestroProtocol.java index 87453ce7d..536f50448 100644 --- a/src/main/java/org/traccar/protocol/MaestroProtocol.java +++ b/src/main/java/org/traccar/protocol/MaestroProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MaestroProtocol extends BaseProtocol { public MaestroProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(160)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ManPowerProtocol.java b/src/main/java/org/traccar/protocol/ManPowerProtocol.java index 49d8b1e9f..8e640d137 100644 --- a/src/main/java/org/traccar/protocol/ManPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ManPowerProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ManPowerProtocol extends BaseProtocol { public ManPowerProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java index d779648e4..6e92d0809 100644 --- a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java +++ b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java @@ -15,18 +15,18 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; - -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import org.traccar.config.Config; public class Mavlink2Protocol extends BaseProtocol { public Mavlink2Protocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 1, 10, 0)); pipeline.addLast(new Mavlink2ProtocolDecoder(Mavlink2Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/MegastekProtocol.java b/src/main/java/org/traccar/protocol/MegastekProtocol.java index e9f5f9fde..130697859 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocol.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MegastekProtocol extends BaseProtocol { public MegastekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MegastekFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java index e8a66e49f..6ef13c51f 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class MeiligaoProtocol extends BaseProtocol { @@ -34,7 +35,7 @@ public class MeiligaoProtocol extends BaseProtocol { Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeiligaoFrameDecoder()); pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this)); pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); @@ -42,7 +43,7 @@ public class MeiligaoProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this)); pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index a25cab06f..528098363 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; 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; @@ -40,7 +39,7 @@ import java.util.regex.Pattern; public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { - private Map photos = new HashMap<>(); + private final Map photos = new HashMap<>(); public MeiligaoProtocolDecoder(Protocol protocol) { super(protocol); @@ -469,7 +468,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } else if (command == MSG_POSITION_IMAGE) { byte imageIndex = buf.readByte(); buf.readUnsignedByte(); // image upload type - String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); + String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); ByteBuf photo = photos.remove(imageIndex); try { position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java index e5b2cf4e7..7784ab093 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -18,11 +18,10 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; 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; @@ -59,7 +58,7 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( + boolean alternative = getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); int outputControlMessageType = alternative diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocol.java b/src/main/java/org/traccar/protocol/MeitrackProtocol.java index 7439ea611..6503fa5e2 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class MeitrackProtocol extends BaseProtocol { @@ -34,7 +35,7 @@ public class MeitrackProtocol extends BaseProtocol { Command.TYPE_SEND_SMS); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeitrackFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new MeitrackProtocolEncoder(MeitrackProtocol.this)); @@ -43,7 +44,7 @@ public class MeitrackProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new MeitrackProtocolEncoder(MeitrackProtocol.this)); pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 6fed56fb6..3ab449350 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; 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; @@ -204,7 +203,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); } - String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); + String deviceModel = getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); if (deviceModel == null) { deviceModel = ""; } diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java index 354e81434..799e14ea2 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java @@ -15,11 +15,10 @@ */ package org.traccar.protocol; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import org.traccar.Protocol; import java.util.Map; @@ -42,7 +41,7 @@ public class MeitrackProtocolEncoder extends StringProtocolEncoder { Map attributes = command.getAttributes(); - boolean alternative = Context.getIdentityManager().lookupAttributeBoolean( + boolean alternative = getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); switch (command.getType()) { diff --git a/src/main/java/org/traccar/protocol/MictrackProtocol.java b/src/main/java/org/traccar/protocol/MictrackProtocol.java index 9fd9666e4..0d1b26909 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MictrackProtocol extends BaseProtocol { public MictrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this)); @@ -34,7 +35,7 @@ public class MictrackProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MilesmateProtocol.java b/src/main/java/org/traccar/protocol/MilesmateProtocol.java index 822711603..cc059c520 100644 --- a/src/main/java/org/traccar/protocol/MilesmateProtocol.java +++ b/src/main/java/org/traccar/protocol/MilesmateProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MilesmateProtocol extends BaseProtocol { public MilesmateProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java index 0cc9598ed..182b5cd91 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class MiniFinderProtocol extends BaseProtocol { @@ -40,7 +41,7 @@ public class MiniFinderProtocol extends BaseProtocol { Command.TYPE_SET_INDICATOR); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";\0", ";")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java index f8801db74..82341e9d0 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java +++ b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class Minifinder2Protocol extends BaseProtocol { public Minifinder2Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1200, 2, 2, 4, 0, true)); pipeline.addLast(new Minifinder2ProtocolDecoder(Minifinder2Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocol.java b/src/main/java/org/traccar/protocol/MobilogixProtocol.java index 28380a2af..37e3d9131 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocol.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MobilogixProtocol extends BaseProtocol { public MobilogixProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ']')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MoovboxProtocol.java b/src/main/java/org/traccar/protocol/MoovboxProtocol.java index 7b554266f..00fcac6ed 100644 --- a/src/main/java/org/traccar/protocol/MoovboxProtocol.java +++ b/src/main/java/org/traccar/protocol/MoovboxProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MoovboxProtocol extends BaseProtocol { public MoovboxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/MotorProtocol.java b/src/main/java/org/traccar/protocol/MotorProtocol.java index 680687e15..d168835bb 100644 --- a/src/main/java/org/traccar/protocol/MotorProtocol.java +++ b/src/main/java/org/traccar/protocol/MotorProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MotorProtocol extends BaseProtocol { public MotorProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MotorProtocolDecoder(MotorProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Mta6Protocol.java b/src/main/java/org/traccar/protocol/Mta6Protocol.java index 14a66ce5c..689ee65dd 100644 --- a/src/main/java/org/traccar/protocol/Mta6Protocol.java +++ b/src/main/java/org/traccar/protocol/Mta6Protocol.java @@ -19,9 +19,9 @@ 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.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; public class Mta6Protocol extends BaseProtocol { @@ -29,12 +29,12 @@ public class Mta6Protocol extends BaseProtocol { public Mta6Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); pipeline.addLast(new Mta6ProtocolDecoder( - Mta6Protocol.this, !Context.getConfig().getBoolean(Keys.PROTOCOL_CAN.withPrefix(getName())))); + Mta6Protocol.this, !config.getBoolean(Keys.PROTOCOL_CAN.withPrefix(getName())))); } }); } diff --git a/src/main/java/org/traccar/protocol/MtxProtocol.java b/src/main/java/org/traccar/protocol/MtxProtocol.java index 44372ce83..c22eb4b96 100644 --- a/src/main/java/org/traccar/protocol/MtxProtocol.java +++ b/src/main/java/org/traccar/protocol/MtxProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MtxProtocol extends BaseProtocol { public MtxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/MxtProtocol.java b/src/main/java/org/traccar/protocol/MxtProtocol.java index dbe43fe45..8269f3f2c 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocol.java +++ b/src/main/java/org/traccar/protocol/MxtProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class MxtProtocol extends BaseProtocol { public MxtProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MxtFrameDecoder()); pipeline.addLast(new MxtProtocolDecoder(MxtProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavigilProtocol.java b/src/main/java/org/traccar/protocol/NavigilProtocol.java index 2c946c39f..e5e3417e9 100644 --- a/src/main/java/org/traccar/protocol/NavigilProtocol.java +++ b/src/main/java/org/traccar/protocol/NavigilProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NavigilProtocol extends BaseProtocol { public NavigilProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavigilFrameDecoder()); pipeline.addLast(new NavigilProtocolDecoder(NavigilProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavisProtocol.java b/src/main/java/org/traccar/protocol/NavisProtocol.java index d5af6838d..146f0cc9f 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NavisProtocol extends BaseProtocol { public NavisProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavisFrameDecoder()); pipeline.addLast(new NavisProtocolDecoder(NavisProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavisetProtocol.java b/src/main/java/org/traccar/protocol/NavisetProtocol.java index 78755ea4d..6423dd401 100644 --- a/src/main/java/org/traccar/protocol/NavisetProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisetProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NavisetProtocol extends BaseProtocol { public NavisetProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavisetFrameDecoder()); pipeline.addLast(new NavisetProtocolDecoder(NavisetProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java index 29ce8c41e..dfc08ece2 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NavtelecomProtocol extends BaseProtocol { public NavtelecomProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavtelecomFrameDecoder()); pipeline.addLast(new NavtelecomProtocolDecoder(NavtelecomProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NeosProtocol.java b/src/main/java/org/traccar/protocol/NeosProtocol.java index e545a9969..a3d79f833 100644 --- a/src/main/java/org/traccar/protocol/NeosProtocol.java +++ b/src/main/java/org/traccar/protocol/NeosProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NeosProtocol extends BaseProtocol { public NeosProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new NeosProtocolDecoder(NeosProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/NetProtocol.java b/src/main/java/org/traccar/protocol/NetProtocol.java index c114d19fc..c39e07337 100644 --- a/src/main/java/org/traccar/protocol/NetProtocol.java +++ b/src/main/java/org/traccar/protocol/NetProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NetProtocol extends BaseProtocol { public NetProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '!')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/NiotProtocol.java b/src/main/java/org/traccar/protocol/NiotProtocol.java index b57b18a3a..659395638 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocol.java +++ b/src/main/java/org/traccar/protocol/NiotProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NiotProtocol extends BaseProtocol { public NiotProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new NiotProtocolDecoder(NiotProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NoranProtocol.java b/src/main/java/org/traccar/protocol/NoranProtocol.java index 3df364c30..adeab8a75 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocol.java +++ b/src/main/java/org/traccar/protocol/NoranProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class NoranProtocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class NoranProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NoranProtocolEncoder(NoranProtocol.this)); pipeline.addLast(new NoranProtocolDecoder(NoranProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NvsProtocol.java b/src/main/java/org/traccar/protocol/NvsProtocol.java index d319b22f3..594b2c325 100644 --- a/src/main/java/org/traccar/protocol/NvsProtocol.java +++ b/src/main/java/org/traccar/protocol/NvsProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class NvsProtocol extends BaseProtocol { public NvsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NvsFrameDecoder()); pipeline.addLast(new NvsProtocolDecoder(NvsProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/NyitechProtocol.java b/src/main/java/org/traccar/protocol/NyitechProtocol.java index 58974be5c..da0a0331c 100644 --- a/src/main/java/org/traccar/protocol/NyitechProtocol.java +++ b/src/main/java/org/traccar/protocol/NyitechProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class NyitechProtocol extends BaseProtocol { public NyitechProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); pipeline.addLast(new NyitechProtocolDecoder(NyitechProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java index 10a55759b..b8ea7433a 100644 --- a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java +++ b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ObdDongleProtocol extends BaseProtocol { public ObdDongleProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1099, 20, 2, 3, 0)); pipeline.addLast(new ObdDongleProtocolDecoder(ObdDongleProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/OigoProtocol.java b/src/main/java/org/traccar/protocol/OigoProtocol.java index 5056f68aa..02d5c40ff 100644 --- a/src/main/java/org/traccar/protocol/OigoProtocol.java +++ b/src/main/java/org/traccar/protocol/OigoProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OigoProtocol extends BaseProtocol { public OigoProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OigoProtocolDecoder(OigoProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/OkoProtocol.java b/src/main/java/org/traccar/protocol/OkoProtocol.java index 9571ccc48..70ea65a29 100644 --- a/src/main/java/org/traccar/protocol/OkoProtocol.java +++ b/src/main/java/org/traccar/protocol/OkoProtocol.java @@ -20,13 +20,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OkoProtocol extends BaseProtocol { public OkoProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '}')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new OkoProtocolDecoder(OkoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/OmnicommProtocol.java b/src/main/java/org/traccar/protocol/OmnicommProtocol.java index 96660cb59..81a7b30ac 100644 --- a/src/main/java/org/traccar/protocol/OmnicommProtocol.java +++ b/src/main/java/org/traccar/protocol/OmnicommProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OmnicommProtocol extends BaseProtocol { public OmnicommProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OmnicommFrameDecoder()); pipeline.addLast(new OmnicommProtocolDecoder(OmnicommProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java index 5ef3260c6..1eed96eed 100644 --- a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java +++ b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OpenGtsProtocol extends BaseProtocol { public OpenGtsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocol.java b/src/main/java/org/traccar/protocol/OrbcommProtocol.java index 2f9f56641..4f27b1efe 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocol.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocol.java @@ -19,21 +19,21 @@ import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestEncoder; import io.netty.handler.codec.http.HttpResponseDecoder; import org.traccar.BaseProtocol; -import org.traccar.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerClient; +import org.traccar.config.Config; public class OrbcommProtocol extends BaseProtocol { public OrbcommProtocol() { addClient(new TrackerClient(getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpRequestEncoder()); pipeline.addLast(new HttpResponseDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); pipeline.addLast(new OrbcommProtocolDecoder(OrbcommProtocol.this)); - pipeline.addLast(new OrbcommProtocolPoller(OrbcommProtocol.this, Context.getConfig())); + pipeline.addLast(new OrbcommProtocolPoller(OrbcommProtocol.this, config)); } }); } diff --git a/src/main/java/org/traccar/protocol/OrionProtocol.java b/src/main/java/org/traccar/protocol/OrionProtocol.java index 8485ae638..cb92f10b7 100644 --- a/src/main/java/org/traccar/protocol/OrionProtocol.java +++ b/src/main/java/org/traccar/protocol/OrionProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OrionProtocol extends BaseProtocol { public OrionProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OrionFrameDecoder()); pipeline.addLast(new OrionProtocolDecoder(OrionProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocol.java b/src/main/java/org/traccar/protocol/OsmAndProtocol.java index d3aa2fd6f..3281a8ae4 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocol.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OsmAndProtocol extends BaseProtocol { public OsmAndProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocol.java b/src/main/java/org/traccar/protocol/OutsafeProtocol.java index c728a404d..ae7cb881f 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocol.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OutsafeProtocol extends BaseProtocol { public OutsafeProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java index 0086371d8..c444f453e 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java @@ -22,13 +22,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class OwnTracksProtocol extends BaseProtocol { public OwnTracksProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java index 08991ab64..c8b046f41 100644 --- a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PacificTrackProtocol extends BaseProtocol { public PacificTrackProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PacificTrackProtocolDecoder(PacificTrackProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/PathAwayProtocol.java b/src/main/java/org/traccar/protocol/PathAwayProtocol.java index 6b5d75c5e..a2f152dda 100644 --- a/src/main/java/org/traccar/protocol/PathAwayProtocol.java +++ b/src/main/java/org/traccar/protocol/PathAwayProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PathAwayProtocol extends BaseProtocol { public PathAwayProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocol.java b/src/main/java/org/traccar/protocol/PiligrimProtocol.java index d88c1ab72..7c0ecaf30 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocol.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PiligrimProtocol extends BaseProtocol { public PiligrimProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(16384)); diff --git a/src/main/java/org/traccar/protocol/PluginProtocol.java b/src/main/java/org/traccar/protocol/PluginProtocol.java index d5f28da9d..2d21f8b41 100644 --- a/src/main/java/org/traccar/protocol/PluginProtocol.java +++ b/src/main/java/org/traccar/protocol/PluginProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PluginProtocol extends BaseProtocol { public PluginProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/PolteProtocol.java b/src/main/java/org/traccar/protocol/PolteProtocol.java index a3e548716..47c64e5ba 100644 --- a/src/main/java/org/traccar/protocol/PolteProtocol.java +++ b/src/main/java/org/traccar/protocol/PolteProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PolteProtocol extends BaseProtocol { public PolteProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/PortmanProtocol.java b/src/main/java/org/traccar/protocol/PortmanProtocol.java index b7faae08a..875c0a599 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocol.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocol.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class PortmanProtocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class PortmanProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/PretraceProtocol.java b/src/main/java/org/traccar/protocol/PretraceProtocol.java index 9d35c1c2f..db1b6d918 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocol.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocol.java @@ -21,6 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class PretraceProtocol extends BaseProtocol { @@ -31,7 +32,7 @@ public class PretraceProtocol extends BaseProtocol { Command.TYPE_POSITION_PERIODIC); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java index 1083a252e..106ba9537 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java @@ -16,10 +16,9 @@ package org.traccar.protocol; import org.traccar.BaseProtocolEncoder; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.model.Command; -import org.traccar.Protocol; public class PretraceProtocolEncoder extends BaseProtocolEncoder { @@ -35,7 +34,7 @@ public class PretraceProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - String uniqueId = Context.getIdentityManager().getById(command.getDeviceId()).getUniqueId(); + String uniqueId = getIdentityManager().getById(command.getDeviceId()).getUniqueId(); switch (command.getType()) { case Command.TYPE_CUSTOM: diff --git a/src/main/java/org/traccar/protocol/PricolProtocol.java b/src/main/java/org/traccar/protocol/PricolProtocol.java index 6821cd949..b009662ac 100644 --- a/src/main/java/org/traccar/protocol/PricolProtocol.java +++ b/src/main/java/org/traccar/protocol/PricolProtocol.java @@ -19,20 +19,21 @@ import io.netty.handler.codec.FixedLengthFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class PricolProtocol extends BaseProtocol { public PricolProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(64)); pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); } }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/ProgressProtocol.java b/src/main/java/org/traccar/protocol/ProgressProtocol.java index aac84205d..235ae1c5e 100644 --- a/src/main/java/org/traccar/protocol/ProgressProtocol.java +++ b/src/main/java/org/traccar/protocol/ProgressProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class ProgressProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class ProgressProtocol extends BaseProtocol { public ProgressProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); pipeline.addLast(new ProgressProtocolDecoder(ProgressProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/PstProtocol.java b/src/main/java/org/traccar/protocol/PstProtocol.java index d8c7008cb..e1f3e18ce 100644 --- a/src/main/java/org/traccar/protocol/PstProtocol.java +++ b/src/main/java/org/traccar/protocol/PstProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class PstProtocol extends BaseProtocol { @@ -28,14 +29,14 @@ public class PstProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PstProtocolEncoder(PstProtocol.this)); pipeline.addLast(new PstProtocolDecoder(PstProtocol.this)); } }); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PstFrameEncoder()); pipeline.addLast(new PstFrameDecoder()); pipeline.addLast(new PstProtocolEncoder(PstProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Pt215Protocol.java b/src/main/java/org/traccar/protocol/Pt215Protocol.java index 09bd9b121..c134afa51 100644 --- a/src/main/java/org/traccar/protocol/Pt215Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt215Protocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Pt215Protocol extends BaseProtocol { public Pt215Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 1, -1, 0)); pipeline.addLast(new Pt215ProtocolDecoder(Pt215Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Pt3000Protocol.java b/src/main/java/org/traccar/protocol/Pt3000Protocol.java index 1ad0026a3..1f783481b 100644 --- a/src/main/java/org/traccar/protocol/Pt3000Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt3000Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Pt3000Protocol extends BaseProtocol { public Pt3000Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, 'd')); // probably wrong pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Pt502Protocol.java b/src/main/java/org/traccar/protocol/Pt502Protocol.java index 56444fb42..64ff4fe06 100644 --- a/src/main/java/org/traccar/protocol/Pt502Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt502Protocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class Pt502Protocol extends BaseProtocol { @@ -32,7 +33,7 @@ public class Pt502Protocol extends BaseProtocol { Command.TYPE_REQUEST_PHOTO); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Pt502FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Pt502ProtocolEncoder(Pt502Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java index 5e24cacdc..0817d527d 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; 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; @@ -175,7 +174,7 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); + String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/main/java/org/traccar/protocol/Pt60Protocol.java b/src/main/java/org/traccar/protocol/Pt60Protocol.java index c502426c5..45084a2f3 100644 --- a/src/main/java/org/traccar/protocol/Pt60Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt60Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Pt60Protocol extends BaseProtocol { public Pt60Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "@R#@", "@E#@")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/R12wProtocol.java b/src/main/java/org/traccar/protocol/R12wProtocol.java index 3726233b4..f3464a3a3 100644 --- a/src/main/java/org/traccar/protocol/R12wProtocol.java +++ b/src/main/java/org/traccar/protocol/R12wProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class R12wProtocol extends BaseProtocol { public R12wProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java index c9db10610..7c7b9a87d 100644 --- a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RaceDynamicsProtocol extends BaseProtocol { public RaceDynamicsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1500)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/RadarProtocol.java b/src/main/java/org/traccar/protocol/RadarProtocol.java index 9783778f0..0b3d836a5 100644 --- a/src/main/java/org/traccar/protocol/RadarProtocol.java +++ b/src/main/java/org/traccar/protocol/RadarProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RadarProtocol extends BaseProtocol { public RadarProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 12, 2, -14, 0)); pipeline.addLast(new RadarProtocolDecoder(RadarProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RaveonProtocol.java b/src/main/java/org/traccar/protocol/RaveonProtocol.java index 44faadb3b..5a1bb88d2 100644 --- a/src/main/java/org/traccar/protocol/RaveonProtocol.java +++ b/src/main/java/org/traccar/protocol/RaveonProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RaveonProtocol extends BaseProtocol { public RaveonProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/RecodaProtocol.java b/src/main/java/org/traccar/protocol/RecodaProtocol.java index 0bc9870bc..9ae837a88 100644 --- a/src/main/java/org/traccar/protocol/RecodaProtocol.java +++ b/src/main/java/org/traccar/protocol/RecodaProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class RecodaProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class RecodaProtocol extends BaseProtocol { public RecodaProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 4, 4, -8, 0, true)); pipeline.addLast(new RecodaProtocolDecoder(RecodaProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java index fae81f7d2..efea6013e 100644 --- a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java +++ b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RetranslatorProtocol extends BaseProtocol { public RetranslatorProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new RetranslatorFrameDecoder()); pipeline.addLast(new RetranslatorProtocolDecoder(RetranslatorProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RitiProtocol.java b/src/main/java/org/traccar/protocol/RitiProtocol.java index de1026672..34c4015b2 100644 --- a/src/main/java/org/traccar/protocol/RitiProtocol.java +++ b/src/main/java/org/traccar/protocol/RitiProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; public class RitiProtocol extends BaseProtocol { @@ -26,7 +27,7 @@ public class RitiProtocol extends BaseProtocol { public RitiProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 105, 2, 3, 0, true)); pipeline.addLast(new RitiProtocolDecoder(RitiProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java index c2c531293..099136272 100644 --- a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RoboTrackProtocol extends BaseProtocol { public RoboTrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new RoboTrackFrameDecoder()); pipeline.addLast(new RoboTrackProtocolDecoder(RoboTrackProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/RstProtocol.java b/src/main/java/org/traccar/protocol/RstProtocol.java index 10d11d493..3a52a215e 100644 --- a/src/main/java/org/traccar/protocol/RstProtocol.java +++ b/src/main/java/org/traccar/protocol/RstProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class RstProtocol extends BaseProtocol { public RstProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new RstProtocolDecoder(RstProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocol.java b/src/main/java/org/traccar/protocol/RuptelaProtocol.java index 5d1f86553..59c5f7942 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocol.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class RuptelaProtocol extends BaseProtocol { @@ -37,7 +38,7 @@ public class RuptelaProtocol extends BaseProtocol { Command.TYPE_SET_ODOMETER); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 2, 0)); pipeline.addLast(new RuptelaProtocolEncoder(RuptelaProtocol.this)); pipeline.addLast(new RuptelaProtocolDecoder(RuptelaProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/S168Protocol.java b/src/main/java/org/traccar/protocol/S168Protocol.java index e78664c40..7186ce93d 100644 --- a/src/main/java/org/traccar/protocol/S168Protocol.java +++ b/src/main/java/org/traccar/protocol/S168Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class S168Protocol extends BaseProtocol { public S168Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SabertekProtocol.java b/src/main/java/org/traccar/protocol/SabertekProtocol.java index 0ec847b60..9c66fd50d 100644 --- a/src/main/java/org/traccar/protocol/SabertekProtocol.java +++ b/src/main/java/org/traccar/protocol/SabertekProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SabertekProtocol extends BaseProtocol { public SabertekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SabertekFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new SabertekProtocolDecoder(SabertekProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SanavProtocol.java b/src/main/java/org/traccar/protocol/SanavProtocol.java index 6799c57e6..e067a2469 100644 --- a/src/main/java/org/traccar/protocol/SanavProtocol.java +++ b/src/main/java/org/traccar/protocol/SanavProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SanavProtocol extends BaseProtocol { public SanavProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new SanavProtocolDecoder(SanavProtocol.this)); @@ -34,7 +35,7 @@ public class SanavProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new SanavProtocolDecoder(SanavProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SanulProtocol.java b/src/main/java/org/traccar/protocol/SanulProtocol.java index 3104e9366..3c268d984 100644 --- a/src/main/java/org/traccar/protocol/SanulProtocol.java +++ b/src/main/java/org/traccar/protocol/SanulProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class SanulProtocol extends BaseProtocol { public SanulProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); pipeline.addLast(new SanulProtocolDecoder(SanulProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/SatsolProtocol.java b/src/main/java/org/traccar/protocol/SatsolProtocol.java index b69fdd1fe..15a43f94d 100644 --- a/src/main/java/org/traccar/protocol/SatsolProtocol.java +++ b/src/main/java/org/traccar/protocol/SatsolProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class SatsolProtocol extends BaseProtocol { public SatsolProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1400, 8, 2, 0, 0, true)); pipeline.addLast(new SatsolProtocolDecoder(SatsolProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocol.java b/src/main/java/org/traccar/protocol/SigfoxProtocol.java index e2f2cbe1f..7666f5589 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocol.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SigfoxProtocol extends BaseProtocol { public SigfoxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/SiwiProtocol.java b/src/main/java/org/traccar/protocol/SiwiProtocol.java index 8963721c8..4cb441e8a 100644 --- a/src/main/java/org/traccar/protocol/SiwiProtocol.java +++ b/src/main/java/org/traccar/protocol/SiwiProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SiwiProtocol extends BaseProtocol { public SiwiProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new SiwiProtocolDecoder(SiwiProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java index 7c6203d86..91830504e 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SkypatrolProtocol extends BaseProtocol { public SkypatrolProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SkypatrolProtocolDecoder(SkypatrolProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java index bcf43f68b..6ae341db3 100644 --- a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java +++ b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SmartSoleProtocol extends BaseProtocol { public SmartSoleProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SmokeyProtocol.java b/src/main/java/org/traccar/protocol/SmokeyProtocol.java index 482c8347c..dc7da9ab5 100644 --- a/src/main/java/org/traccar/protocol/SmokeyProtocol.java +++ b/src/main/java/org/traccar/protocol/SmokeyProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SmokeyProtocol extends BaseProtocol { public SmokeyProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SmokeyProtocolDecoder(SmokeyProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java index 53a948cdc..9f9ef5a87 100644 --- a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java +++ b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SolarPoweredProtocol extends BaseProtocol { public SolarPoweredProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuabaoFrameDecoder()); pipeline.addLast(new SolarPoweredProtocolDecoder(SolarPoweredProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/SpotProtocol.java b/src/main/java/org/traccar/protocol/SpotProtocol.java index bbf0e8d8a..238dc3b72 100644 --- a/src/main/java/org/traccar/protocol/SpotProtocol.java +++ b/src/main/java/org/traccar/protocol/SpotProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SpotProtocol extends BaseProtocol { public SpotProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65535)); diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocol.java b/src/main/java/org/traccar/protocol/StarLinkProtocol.java index 5630722ee..fa9cdc30a 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocol.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class StarLinkProtocol extends BaseProtocol { public StarLinkProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index 5e631017e..afccb3a6b 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; @@ -67,7 +66,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } public String[] getFormat(long deviceId) { - return Context.getIdentityManager().lookupAttributeString( + return getIdentityManager().lookupAttributeString( deviceId, getProtocolName() + ".format", format, false, false).split(","); } @@ -76,7 +75,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } public DateFormat getDateFormat(long deviceId) { - DateFormat dateFormat = new SimpleDateFormat(Context.getIdentityManager().lookupAttributeString( + DateFormat dateFormat = new SimpleDateFormat(getIdentityManager().lookupAttributeString( deviceId, getProtocolName() + ".dateFormat", this.dateFormat, false, false)); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); return dateFormat; diff --git a/src/main/java/org/traccar/protocol/StarcomProtocol.java b/src/main/java/org/traccar/protocol/StarcomProtocol.java index 63a6143a6..8f1c4bc3f 100644 --- a/src/main/java/org/traccar/protocol/StarcomProtocol.java +++ b/src/main/java/org/traccar/protocol/StarcomProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class StarcomProtocol extends BaseProtocol { public StarcomProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StarcomProtocolDecoder(StarcomProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/StartekProtocol.java b/src/main/java/org/traccar/protocol/StartekProtocol.java index 32f1c5a29..14ae1564e 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocol.java +++ b/src/main/java/org/traccar/protocol/StartekProtocol.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class StartekProtocol extends BaseProtocol { @@ -33,7 +34,7 @@ public class StartekProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/StbProtocol.java b/src/main/java/org/traccar/protocol/StbProtocol.java index 002ed86c7..206b29e29 100644 --- a/src/main/java/org/traccar/protocol/StbProtocol.java +++ b/src/main/java/org/traccar/protocol/StbProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class StbProtocol extends BaseProtocol { public StbProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Stl060Protocol.java b/src/main/java/org/traccar/protocol/Stl060Protocol.java index 2711e936b..0ac0490e3 100644 --- a/src/main/java/org/traccar/protocol/Stl060Protocol.java +++ b/src/main/java/org/traccar/protocol/Stl060Protocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Stl060Protocol extends BaseProtocol { public Stl060Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Stl060FrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocol.java b/src/main/java/org/traccar/protocol/SuntechProtocol.java index 199885537..ae55d2a14 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocol.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class SuntechProtocol extends BaseProtocol { @@ -34,7 +35,7 @@ public class SuntechProtocol extends BaseProtocol { Command.TYPE_ALARM_DISARM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SuntechFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new SuntechProtocolEncoder(SuntechProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 8926f427e..fca7661f7 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -72,7 +71,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public int getProtocolType(long deviceId) { - return Context.getIdentityManager().lookupAttributeInteger( + return getIdentityManager().lookupAttributeInteger( deviceId, getProtocolName() + ".protocolType", protocolType, false, true); } @@ -81,7 +80,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isHbm(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( + return getIdentityManager().lookupAttributeBoolean( deviceId, getProtocolName() + ".hbm", hbm, false, true); } @@ -90,7 +89,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeAdc(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( + return getIdentityManager().lookupAttributeBoolean( deviceId, getProtocolName() + ".includeAdc", includeAdc, false, true); } @@ -99,7 +98,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeRpm(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( + return getIdentityManager().lookupAttributeBoolean( deviceId, getProtocolName() + ".includeRpm", includeRpm, false, true); } @@ -108,7 +107,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeTemp(long deviceId) { - return Context.getIdentityManager().lookupAttributeBoolean( + return getIdentityManager().lookupAttributeBoolean( deviceId, getProtocolName() + ".includeTemp", includeTemp, false, true); } diff --git a/src/main/java/org/traccar/protocol/SupermateProtocol.java b/src/main/java/org/traccar/protocol/SupermateProtocol.java index 46625ddc7..59c68d7d0 100644 --- a/src/main/java/org/traccar/protocol/SupermateProtocol.java +++ b/src/main/java/org/traccar/protocol/SupermateProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SupermateProtocol extends BaseProtocol { public SupermateProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/SviasProtocol.java b/src/main/java/org/traccar/protocol/SviasProtocol.java index accfa173f..d9b413a9e 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocol.java +++ b/src/main/java/org/traccar/protocol/SviasProtocol.java @@ -21,7 +21,7 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; - +import org.traccar.config.Config; import org.traccar.model.Command; public class SviasProtocol extends BaseProtocol { @@ -38,7 +38,7 @@ public class SviasProtocol extends BaseProtocol { Command.TYPE_ALARM_REMOVE); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "]")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SwiftechProtocol.java b/src/main/java/org/traccar/protocol/SwiftechProtocol.java index 5e2597b93..3222a7038 100644 --- a/src/main/java/org/traccar/protocol/SwiftechProtocol.java +++ b/src/main/java/org/traccar/protocol/SwiftechProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class SwiftechProtocol extends BaseProtocol { public SwiftechProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/T55Protocol.java b/src/main/java/org/traccar/protocol/T55Protocol.java index f5ec19094..f3f7b4a74 100644 --- a/src/main/java/org/traccar/protocol/T55Protocol.java +++ b/src/main/java/org/traccar/protocol/T55Protocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class T55Protocol extends BaseProtocol { public T55Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); @@ -36,7 +37,7 @@ public class T55Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new T55ProtocolDecoder(T55Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 230d29216..acfab5598 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -17,7 +17,6 @@ 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; @@ -130,7 +129,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession, String sentence, SocketAddress remoteAddress, Channel channel) { if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel) - && Context.getIdentityManager().lookupAttributeBoolean( + && getIdentityManager().lookupAttributeBoolean( deviceSession.getDeviceId(), getProtocolName() + ".ack", false, false, true)) { channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); } diff --git a/src/main/java/org/traccar/protocol/T57Protocol.java b/src/main/java/org/traccar/protocol/T57Protocol.java index f67f82318..e228c5c0d 100644 --- a/src/main/java/org/traccar/protocol/T57Protocol.java +++ b/src/main/java/org/traccar/protocol/T57Protocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class T57Protocol extends BaseProtocol { public T57Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new T57FrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/T800xProtocol.java b/src/main/java/org/traccar/protocol/T800xProtocol.java index 8b91265cb..fa692c792 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocol.java +++ b/src/main/java/org/traccar/protocol/T800xProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class T800xProtocol extends BaseProtocol { @@ -28,7 +29,7 @@ public class T800xProtocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, -5, 0)); pipeline.addLast(new T800xProtocolEncoder(T800xProtocol.this)); pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java b/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java index 02c111b01..48419af2a 100644 --- a/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java +++ b/src/main/java/org/traccar/protocol/TaipPrefixEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,14 @@ */ package org.traccar.protocol; +import com.google.inject.Inject; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageEncoder; -import org.traccar.Context; import org.traccar.Protocol; +import org.traccar.config.Config; import org.traccar.config.Keys; import java.util.List; @@ -30,14 +31,20 @@ import java.util.List; public class TaipPrefixEncoder extends MessageToMessageEncoder { private final Protocol protocol; + private Config config; public TaipPrefixEncoder(Protocol protocol) { this.protocol = protocol; } + @Inject + public void setConfig(Config config) { + this.config = config; + } + @Override - protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { - if (Context.getConfig().getBoolean(Keys.PROTOCOL_PREFIX.withPrefix(protocol.getName()))) { + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) { + if (config.getBoolean(Keys.PROTOCOL_PREFIX.withPrefix(protocol.getName()))) { out.add(Unpooled.wrappedBuffer(Unpooled.wrappedBuffer(new byte[] {0x20, 0x20, 0x06, 0x00}), msg.retain())); } else { out.add(msg.retain()); diff --git a/src/main/java/org/traccar/protocol/TaipProtocol.java b/src/main/java/org/traccar/protocol/TaipProtocol.java index 0966cfd7c..caa4f4c97 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocol.java +++ b/src/main/java/org/traccar/protocol/TaipProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TaipProtocol extends BaseProtocol { public TaipProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '<')); pipeline.addLast(new TaipPrefixEncoder(TaipProtocol.this)); pipeline.addLast(new StringDecoder()); @@ -37,7 +38,7 @@ public class TaipProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TaipPrefixEncoder(TaipProtocol.this)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TechTltProtocol.java b/src/main/java/org/traccar/protocol/TechTltProtocol.java index 0cffb452d..e421990a7 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocol.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TechTltProtocol extends BaseProtocol { public TechTltProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new TechTltProtocolDecoder(TechTltProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java index a217ea738..48ea825a5 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TechtoCruzProtocol extends BaseProtocol { public TechtoCruzProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TechtoCruzFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TekProtocol.java b/src/main/java/org/traccar/protocol/TekProtocol.java index c1d78e6f5..0aeab9be3 100644 --- a/src/main/java/org/traccar/protocol/TekProtocol.java +++ b/src/main/java/org/traccar/protocol/TekProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TekProtocol extends BaseProtocol { public TekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TekFrameDecoder()); pipeline.addLast(new TekProtocolDecoder(TekProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TelemaxProtocol.java b/src/main/java/org/traccar/protocol/TelemaxProtocol.java index 838da9df1..9bbdf7ad7 100644 --- a/src/main/java/org/traccar/protocol/TelemaxProtocol.java +++ b/src/main/java/org/traccar/protocol/TelemaxProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TelemaxProtocol extends BaseProtocol { public TelemaxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TelicProtocol.java b/src/main/java/org/traccar/protocol/TelicProtocol.java index 991befa19..6d47a7a7f 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocol.java +++ b/src/main/java/org/traccar/protocol/TelicProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TelicProtocol extends BaseProtocol { public TelicProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TelicFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java index 5817b86be..e2ee8ef19 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class TeltonikaProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class TeltonikaProtocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TeltonikaFrameDecoder()); pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this)); pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false)); @@ -35,7 +36,7 @@ public class TeltonikaProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { 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 407488527..03a5a00ea 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -20,7 +20,6 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; 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; @@ -149,7 +148,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { channel, remoteAddress, photoId, photo.writerIndex(), Math.min(IMAGE_PACKET_MAX, photo.writableBytes())); } else { - String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); + String uniqueId = getIdentityManager().getById(position.getDeviceId()).getUniqueId(); photos.remove(photoId); try { position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java index 0303b4b5a..8b62db8c0 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TeraTrackProtocol extends BaseProtocol { public TeraTrackProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java index ece1b0544..076386818 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ThinkPowerProtocol extends BaseProtocol { public ThinkPowerProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, 2, 0)); pipeline.addLast(new ThinkPowerProtocolDecoder(ThinkPowerProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java index ca1237cef..6c684a8b4 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class ThinkRaceProtocol extends BaseProtocol { public ThinkRaceProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2 + 12 + 1 + 1, 2, 2, 0)); pipeline.addLast(new ThinkRaceProtocolDecoder(ThinkRaceProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Tk102Protocol.java b/src/main/java/org/traccar/protocol/Tk102Protocol.java index 9f2463cd6..8eb923d50 100644 --- a/src/main/java/org/traccar/protocol/Tk102Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk102Protocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Tk102Protocol extends BaseProtocol { public Tk102Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1 + 1 + 10, 1, 1, 0)); pipeline.addLast(new Tk102ProtocolDecoder(Tk102Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Tk103Protocol.java b/src/main/java/org/traccar/protocol/Tk103Protocol.java index ff0bedfb7..bca16928f 100644 --- a/src/main/java/org/traccar/protocol/Tk103Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk103Protocol.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class Tk103Protocol extends BaseProtocol { @@ -47,7 +48,7 @@ public class Tk103Protocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Tk103FrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); @@ -57,7 +58,7 @@ public class Tk103Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new Tk103ProtocolEncoder(Tk103Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java index 5d7e63920..a0e9b199c 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java @@ -16,10 +16,9 @@ */ package org.traccar.protocol; -import org.traccar.Context; +import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; import org.traccar.model.Command; -import org.traccar.Protocol; public class Tk103ProtocolEncoder extends StringProtocolEncoder { @@ -42,7 +41,7 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = forceAlternative || Context.getIdentityManager().lookupAttributeBoolean( + boolean alternative = forceAlternative || getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); initDevicePassword(command, "123456"); diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java index 12fd92afa..8c8777074 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Tlt2hProtocol extends BaseProtocol { public Tlt2hProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, "##\r\n")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TlvProtocol.java b/src/main/java/org/traccar/protocol/TlvProtocol.java index 94f5da94f..5b8de8fbe 100644 --- a/src/main/java/org/traccar/protocol/TlvProtocol.java +++ b/src/main/java/org/traccar/protocol/TlvProtocol.java @@ -19,13 +19,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TlvProtocol extends BaseProtocol { public TlvProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); pipeline.addLast(new TlvProtocolDecoder(TlvProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TmgProtocol.java b/src/main/java/org/traccar/protocol/TmgProtocol.java index 020332ce7..6c29a8854 100644 --- a/src/main/java/org/traccar/protocol/TmgProtocol.java +++ b/src/main/java/org/traccar/protocol/TmgProtocol.java @@ -20,13 +20,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TmgProtocol extends BaseProtocol { public TmgProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TmgFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TopflytechProtocol.java b/src/main/java/org/traccar/protocol/TopflytechProtocol.java index 303072bdb..47162a42d 100644 --- a/src/main/java/org/traccar/protocol/TopflytechProtocol.java +++ b/src/main/java/org/traccar/protocol/TopflytechProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TopflytechProtocol extends BaseProtocol { public TopflytechProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TopinProtocol.java b/src/main/java/org/traccar/protocol/TopinProtocol.java index d28afbf94..3c1a7eed3 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocol.java +++ b/src/main/java/org/traccar/protocol/TopinProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class TopinProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class TopinProtocol extends BaseProtocol { Command.TYPE_SOS_NUMBER); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TopinProtocolEncoder(TopinProtocol.this)); pipeline.addLast(new TopinProtocolDecoder(TopinProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java index 417a4d6b0..3322d1dc0 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocol.java +++ b/src/main/java/org/traccar/protocol/TotemProtocol.java @@ -20,6 +20,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class TotemProtocol extends BaseProtocol { @@ -48,7 +49,7 @@ public class TotemProtocol extends BaseProtocol { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TotemFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Tr20Protocol.java b/src/main/java/org/traccar/protocol/Tr20Protocol.java index 1b71db03f..dc6c013c8 100644 --- a/src/main/java/org/traccar/protocol/Tr20Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr20Protocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Tr20Protocol extends BaseProtocol { public Tr20Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -36,7 +37,7 @@ public class Tr20Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Tr20ProtocolDecoder(Tr20Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Tr900Protocol.java b/src/main/java/org/traccar/protocol/Tr900Protocol.java index b70521b35..615987952 100644 --- a/src/main/java/org/traccar/protocol/Tr900Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr900Protocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Tr900Protocol extends BaseProtocol { public Tr900Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -36,7 +37,7 @@ public class Tr900Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new Tr900ProtocolDecoder(Tr900Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/TrackboxProtocol.java b/src/main/java/org/traccar/protocol/TrackboxProtocol.java index 5da5abd64..1c756e26b 100644 --- a/src/main/java/org/traccar/protocol/TrackboxProtocol.java +++ b/src/main/java/org/traccar/protocol/TrackboxProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TrackboxProtocol extends BaseProtocol { public TrackboxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TrakMateProtocol.java b/src/main/java/org/traccar/protocol/TrakMateProtocol.java index bda5df10f..25f6d9470 100644 --- a/src/main/java/org/traccar/protocol/TrakMateProtocol.java +++ b/src/main/java/org/traccar/protocol/TrakMateProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TrakMateProtocol extends BaseProtocol { public TrakMateProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/TramigoProtocol.java b/src/main/java/org/traccar/protocol/TramigoProtocol.java index f683ccc5d..2c8013523 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocol.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TramigoProtocol extends BaseProtocol { public TramigoProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TramigoFrameDecoder()); pipeline.addLast(new TramigoProtocolDecoder(TramigoProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/TrvProtocol.java b/src/main/java/org/traccar/protocol/TrvProtocol.java index 99a164cf1..a8884eb5e 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocol.java +++ b/src/main/java/org/traccar/protocol/TrvProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TrvProtocol extends BaseProtocol { public TrvProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Tt8850Protocol.java b/src/main/java/org/traccar/protocol/Tt8850Protocol.java index 66a13da9e..b11411817 100644 --- a/src/main/java/org/traccar/protocol/Tt8850Protocol.java +++ b/src/main/java/org/traccar/protocol/Tt8850Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Tt8850Protocol extends BaseProtocol { public Tt8850Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "$")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TytanProtocol.java b/src/main/java/org/traccar/protocol/TytanProtocol.java index 32e9acae1..2ca1ff8e8 100644 --- a/src/main/java/org/traccar/protocol/TytanProtocol.java +++ b/src/main/java/org/traccar/protocol/TytanProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class TytanProtocol extends BaseProtocol { public TytanProtocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TytanProtocolDecoder(TytanProtocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/TzoneProtocol.java b/src/main/java/org/traccar/protocol/TzoneProtocol.java index 6e855d138..9bb550e39 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocol.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocol.java @@ -15,18 +15,18 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; - -import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import org.traccar.config.Config; public class TzoneProtocol extends BaseProtocol { public TzoneProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 2, 2, 0)); pipeline.addLast(new TzoneProtocolDecoder(TzoneProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocol.java b/src/main/java/org/traccar/protocol/UlbotechProtocol.java index dfe5235f0..d149bbd58 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocol.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class UlbotechProtocol extends BaseProtocol { @@ -27,7 +28,7 @@ public class UlbotechProtocol extends BaseProtocol { Command.TYPE_CUSTOM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new UlbotechFrameDecoder()); pipeline.addLast(new UlbotechProtocolEncoder(UlbotechProtocol.this)); pipeline.addLast(new UlbotechProtocolDecoder(UlbotechProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/UproProtocol.java b/src/main/java/org/traccar/protocol/UproProtocol.java index 4e60ffeb6..5bfa6d76d 100644 --- a/src/main/java/org/traccar/protocol/UproProtocol.java +++ b/src/main/java/org/traccar/protocol/UproProtocol.java @@ -20,13 +20,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class UproProtocol extends BaseProtocol { public UproProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringEncoder()); pipeline.addLast(new UproProtocolDecoder(UproProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/UuxProtocol.java b/src/main/java/org/traccar/protocol/UuxProtocol.java index 41b59d829..61f622f68 100644 --- a/src/main/java/org/traccar/protocol/UuxProtocol.java +++ b/src/main/java/org/traccar/protocol/UuxProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class UuxProtocol extends BaseProtocol { public UuxProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 1)); pipeline.addLast(new UuxProtocolDecoder(UuxProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/V680Protocol.java b/src/main/java/org/traccar/protocol/V680Protocol.java index dc0922cd4..488dcc4e0 100644 --- a/src/main/java/org/traccar/protocol/V680Protocol.java +++ b/src/main/java/org/traccar/protocol/V680Protocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class V680Protocol extends BaseProtocol { public V680Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); @@ -36,7 +37,7 @@ public class V680Protocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new V680ProtocolDecoder(V680Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/VisiontekProtocol.java b/src/main/java/org/traccar/protocol/VisiontekProtocol.java index 2c6af45a8..5d3e3c097 100644 --- a/src/main/java/org/traccar/protocol/VisiontekProtocol.java +++ b/src/main/java/org/traccar/protocol/VisiontekProtocol.java @@ -21,13 +21,14 @@ import org.traccar.BaseProtocol; import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class VisiontekProtocol extends BaseProtocol { public VisiontekProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/VnetProtocol.java b/src/main/java/org/traccar/protocol/VnetProtocol.java index 0fed30e13..41522935e 100644 --- a/src/main/java/org/traccar/protocol/VnetProtocol.java +++ b/src/main/java/org/traccar/protocol/VnetProtocol.java @@ -19,6 +19,7 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import java.nio.ByteOrder; @@ -27,7 +28,7 @@ public class VnetProtocol extends BaseProtocol { public VnetProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1500, 4, 2, 12, 0, true)); pipeline.addLast(new VnetProtocolDecoder(VnetProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Vt200Protocol.java b/src/main/java/org/traccar/protocol/Vt200Protocol.java index 2a9ef6ab5..655514e94 100644 --- a/src/main/java/org/traccar/protocol/Vt200Protocol.java +++ b/src/main/java/org/traccar/protocol/Vt200Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Vt200Protocol extends BaseProtocol { public Vt200Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Vt200FrameDecoder()); pipeline.addLast(new Vt200ProtocolDecoder(Vt200Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/VtfmsProtocol.java b/src/main/java/org/traccar/protocol/VtfmsProtocol.java index 2826a86e6..8bedd455d 100644 --- a/src/main/java/org/traccar/protocol/VtfmsProtocol.java +++ b/src/main/java/org/traccar/protocol/VtfmsProtocol.java @@ -15,18 +15,18 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; - -import io.netty.handler.codec.string.StringDecoder; +import org.traccar.config.Config; public class VtfmsProtocol extends BaseProtocol { public VtfmsProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new VtfmsFrameDecoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new VtfmsProtocolDecoder(VtfmsProtocol.this)); @@ -34,7 +34,7 @@ public class VtfmsProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); pipeline.addLast(new VtfmsProtocolDecoder(VtfmsProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/WatchProtocol.java b/src/main/java/org/traccar/protocol/WatchProtocol.java index 6dc3bf9fb..fe96b3828 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocol.java +++ b/src/main/java/org/traccar/protocol/WatchProtocol.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; public class WatchProtocol extends BaseProtocol { @@ -42,7 +43,7 @@ public class WatchProtocol extends BaseProtocol { Command.TYPE_SET_INDICATOR); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WatchFrameDecoder()); pipeline.addLast(new WatchProtocolEncoder(WatchProtocol.this)); pipeline.addLast(new WatchProtocolDecoder(WatchProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/WialonProtocol.java b/src/main/java/org/traccar/protocol/WialonProtocol.java index cb6ea5319..204bdd341 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocol.java +++ b/src/main/java/org/traccar/protocol/WialonProtocol.java @@ -15,17 +15,16 @@ */ 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.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; -import io.netty.handler.codec.LineBasedFrameDecoder; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; - import java.nio.charset.StandardCharsets; public class WialonProtocol extends BaseProtocol { @@ -38,9 +37,9 @@ public class WialonProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); - boolean utf8 = Context.getConfig().getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); + boolean utf8 = config.getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); if (utf8) { pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8)); pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); @@ -54,9 +53,9 @@ public class WialonProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); - boolean utf8 = Context.getConfig().getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); + boolean utf8 = config.getBoolean(Keys.PROTOCOL_UTF8.withPrefix(getName())); if (utf8) { pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8)); pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); diff --git a/src/main/java/org/traccar/protocol/WliProtocol.java b/src/main/java/org/traccar/protocol/WliProtocol.java index c10ebf505..aab25abca 100644 --- a/src/main/java/org/traccar/protocol/WliProtocol.java +++ b/src/main/java/org/traccar/protocol/WliProtocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class WliProtocol extends BaseProtocol { public WliProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WliFrameDecoder()); pipeline.addLast(new WliProtocolDecoder(WliProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/WondexProtocol.java b/src/main/java/org/traccar/protocol/WondexProtocol.java index 6401fde85..dc3ed3413 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocol.java +++ b/src/main/java/org/traccar/protocol/WondexProtocol.java @@ -15,13 +15,13 @@ */ package org.traccar.protocol; +import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; -import io.netty.handler.codec.string.StringEncoder; - public class WondexProtocol extends BaseProtocol { public WondexProtocol() { @@ -42,7 +42,7 @@ public class WondexProtocol extends BaseProtocol { Command.TYPE_IDENTIFICATION); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WondexFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new WondexProtocolEncoder(WondexProtocol.this)); @@ -51,7 +51,7 @@ public class WondexProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new WondexProtocolEncoder(WondexProtocol.this)); pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/WristbandProtocol.java b/src/main/java/org/traccar/protocol/WristbandProtocol.java index 1e5ef2c01..38f85f45a 100644 --- a/src/main/java/org/traccar/protocol/WristbandProtocol.java +++ b/src/main/java/org/traccar/protocol/WristbandProtocol.java @@ -19,13 +19,14 @@ import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class WristbandProtocol extends BaseProtocol { public WristbandProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, 3, 0)); pipeline.addLast(new WristbandProtocolDecoder(WristbandProtocol.this)); } diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index 265841c77..d64190ad8 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Xexun2Protocol extends BaseProtocol { public Xexun2Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xexun2FrameDecoder()); pipeline.addLast(new Xexun2ProtocolDecoder(Xexun2Protocol.this)); } diff --git a/src/main/java/org/traccar/protocol/XexunProtocol.java b/src/main/java/org/traccar/protocol/XexunProtocol.java index b83c4e445..2e6d4393b 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocol.java +++ b/src/main/java/org/traccar/protocol/XexunProtocol.java @@ -15,17 +15,16 @@ */ 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.Context; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; -import io.netty.handler.codec.LineBasedFrameDecoder; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; - public class XexunProtocol extends BaseProtocol { public XexunProtocol() { @@ -34,8 +33,8 @@ public class XexunProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { - boolean full = Context.getConfig().getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getName())); + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + boolean full = config.getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getName())); if (full) { pipeline.addLast(new LineBasedFrameDecoder(1024)); // tracker bug \n\r } else { diff --git a/src/main/java/org/traccar/protocol/XirgoProtocol.java b/src/main/java/org/traccar/protocol/XirgoProtocol.java index 1be5b6c4b..f986ca3e6 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocol.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocol.java @@ -15,15 +15,15 @@ */ 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; +import org.traccar.config.Config; import org.traccar.model.Command; -import io.netty.handler.codec.string.StringDecoder; -import io.netty.handler.codec.string.StringEncoder; - public class XirgoProtocol extends BaseProtocol { public XirgoProtocol() { @@ -31,7 +31,7 @@ public class XirgoProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); @@ -41,7 +41,7 @@ public class XirgoProtocol extends BaseProtocol { }); addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); pipeline.addLast(new XirgoProtocolEncoder(XirgoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/Xrb28Protocol.java b/src/main/java/org/traccar/protocol/Xrb28Protocol.java index 5d8af418b..53eed5595 100644 --- a/src/main/java/org/traccar/protocol/Xrb28Protocol.java +++ b/src/main/java/org/traccar/protocol/Xrb28Protocol.java @@ -21,6 +21,7 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; import org.traccar.model.Command; import java.nio.charset.StandardCharsets; @@ -36,7 +37,7 @@ public class Xrb28Protocol extends BaseProtocol { Command.TYPE_ALARM_DISARM); addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder(StandardCharsets.ISO_8859_1)); pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Xt013Protocol.java b/src/main/java/org/traccar/protocol/Xt013Protocol.java index ebb3c123f..aaed47c89 100644 --- a/src/main/java/org/traccar/protocol/Xt013Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt013Protocol.java @@ -15,20 +15,20 @@ */ package org.traccar.protocol; -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; - 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; +import org.traccar.config.Config; public class Xt013Protocol extends BaseProtocol { public Xt013Protocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Xt2400Protocol.java b/src/main/java/org/traccar/protocol/Xt2400Protocol.java index 9427876c8..81567b82c 100644 --- a/src/main/java/org/traccar/protocol/Xt2400Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt2400Protocol.java @@ -18,13 +18,14 @@ package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class Xt2400Protocol extends BaseProtocol { public Xt2400Protocol() { addServer(new TrackerServer(true, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xt2400ProtocolDecoder(Xt2400Protocol.this)); } }); diff --git a/src/main/java/org/traccar/protocol/YwtProtocol.java b/src/main/java/org/traccar/protocol/YwtProtocol.java index c525b75cf..6dd8623c9 100644 --- a/src/main/java/org/traccar/protocol/YwtProtocol.java +++ b/src/main/java/org/traccar/protocol/YwtProtocol.java @@ -21,13 +21,14 @@ import io.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; +import org.traccar.config.Config; public class YwtProtocol extends BaseProtocol { public YwtProtocol() { addServer(new TrackerServer(false, getName()) { @Override - protected void addProtocolHandlers(PipelineBuilder pipeline) { + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 35374a363..2eedd4bd8 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,5 +1,7 @@ package org.traccar; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.traccar.config.Config; import org.traccar.database.ConnectionManager; import org.traccar.database.IdentityManager; @@ -7,7 +9,12 @@ import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.model.Device; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class BaseTest { @@ -20,7 +27,14 @@ public class BaseTest { var device = mock(Device.class); when(device.getId()).thenReturn(1L); var identityManager = mock(IdentityManager.class); + when(identityManager.getById(anyLong())).thenReturn(device); when(identityManager.getByUniqueId(any())).thenReturn(device); + when(identityManager.lookupAttributeBoolean(anyLong(), any(), anyBoolean(), anyBoolean(), anyBoolean())) + .thenAnswer(invocation -> invocation.getArguments()[2]); + when(identityManager.lookupAttributeString(anyLong(), any(), any(), anyBoolean(), anyBoolean())) + .thenAnswer(invocation -> invocation.getArguments()[2]); + when(identityManager.lookupAttributeInteger(anyLong(), any(), anyInt(), anyBoolean(), anyBoolean())) + .thenAnswer(invocation -> invocation.getArguments()[2]); decoder.setIdentityManager(identityManager); decoder.setConnectionManager(mock(ConnectionManager.class)); decoder.setStatisticsManager(mock(StatisticsManager.class)); @@ -33,6 +47,15 @@ public class BaseTest { } protected T inject(T encoder) throws Exception { + var device = mock(Device.class); + when(device.getId()).thenReturn(1L); + when(device.getUniqueId()).thenReturn("123456789012345"); + var identityManager = mock(IdentityManager.class); + when(identityManager.getDevicePassword(anyLong(), any(), any())) + .thenAnswer(invocation -> invocation.getArguments()[2]); + when(identityManager.getById(anyLong())).thenReturn(device); + when(identityManager.getByUniqueId(any())).thenReturn(device); + encoder.setIdentityManager(identityManager); return encoder; } diff --git a/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java index 89ddef849..79f37c4e4 100644 --- a/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java @@ -27,7 +27,7 @@ public class AdmProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new AdmProtocolEncoder(null); + var encoder = inject(new AdmProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java index c72012e5a..bfaa3ccd8 100644 --- a/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class BceProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new BceProtocolEncoder(null); + var encoder = inject(new BceProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java index cdf6a7c3b..9b3a285da 100644 --- a/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class CastelProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new CastelProtocolEncoder(null); + var encoder = inject(new CastelProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java index 9d42bd65d..bb5d4979d 100644 --- a/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class CellocatorProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new CellocatorProtocolEncoder(null); + var encoder = inject(new CellocatorProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java index 2722f6474..6da9856c8 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 { - var encoder = new CityeasyProtocolEncoder(null); + var encoder = inject(new CityeasyProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/EasyTrackProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/EasyTrackProtocolEncoderTest.java index 79b4e66e3..1e1934435 100644 --- a/src/test/java/org/traccar/protocol/EasyTrackProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/EasyTrackProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class EasyTrackProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeEngineStop() { + public void testEncodeEngineStop() throws Exception { - var encoder = new EasyTrackProtocolEncoder(null); + var encoder = inject(new EasyTrackProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java index 616ca0b52..380888843 100644 --- a/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java @@ -7,15 +7,28 @@ import org.traccar.model.Command; public class EelinkProtocolEncoderTest extends ProtocolTest { @Test - public void testEncode() throws Exception { + public void testEncodeTcp() throws Exception { + + var encoder = inject(new EelinkProtocolEncoder(null, false)); Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); - verifyCommand(new EelinkProtocolEncoder(null, false), command, binary("676780000f0000010000000052454c41592c3123")); + verifyCommand(encoder, command, binary("676780000f0000010000000052454c41592c3123")); + + } + + @Test + public void testEncodeUdp() throws Exception { + + var encoder = inject(new EelinkProtocolEncoder(null, true)); + + Command command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_ENGINE_STOP); - verifyCommand(new EelinkProtocolEncoder(null, true), command, binary("454c001eb41a0123456789012345676780000f0000010000000052454c41592c3123")); + verifyCommand(encoder, command, binary("454c001eb41a0123456789012345676780000f0000010000000052454c41592c3123")); } diff --git a/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java index 88be3ebc9..3ea8de5d6 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 { - var encoder = new EsealProtocolEncoder(null); + var encoder = inject(new EsealProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java index 2da7f0842..c3352f510 100644 --- a/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class FifotrackProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new FifotrackProtocolEncoder(null); + var encoder = inject(new FifotrackProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java index b25100c48..29fe4cc94 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 { - var encoder = new GalileoProtocolEncoder(null); + var encoder = inject(new GalileoProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/GlobalSatProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GlobalSatProtocolEncoderTest.java index ae4b52167..9001c4bf3 100644 --- a/src/test/java/org/traccar/protocol/GlobalSatProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/GlobalSatProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class GlobalSatProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeAlarmDismiss() { + public void testEncodeAlarmDismiss() throws Exception { - var encoder = new GlobalSatProtocolEncoder(null); + var encoder = inject(new GlobalSatProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -22,9 +22,9 @@ public class GlobalSatProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeOutputControl() { + public void testEncodeOutputControl() throws Exception { - var encoder = new GlobalSatProtocolEncoder(null); + var encoder = inject(new GlobalSatProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java index 5edfbf629..f6cbe6d17 100644 --- a/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class Gps103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionPeriodic() throws Exception { - var encoder = new Gps103ProtocolEncoder(null); + var encoder = inject(new Gps103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -25,7 +25,7 @@ public class Gps103ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustom() throws Exception { - var encoder = new Gps103ProtocolEncoder(null); + var encoder = inject(new Gps103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java index 79165d9dc..13463ea39 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class Gt06ProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new Gt06ProtocolEncoder(null); + var encoder = inject(new Gt06ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java index 3ed0a7e91..1be9421bb 100644 --- a/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java @@ -1,5 +1,6 @@ package org.traccar.protocol; +import org.junit.Before; import org.junit.Test; import org.traccar.ProtocolTest; import org.traccar.model.Command; @@ -14,10 +15,15 @@ import static org.junit.Assert.assertEquals; public class H02ProtocolEncoderTest extends ProtocolTest { - private H02ProtocolEncoder encoder = new H02ProtocolEncoder(null); - private Date time = Date.from( + private H02ProtocolEncoder encoder; + private final Date time = Date.from( LocalDateTime.of(LocalDate.now(), LocalTime.of(1, 2, 3)).atZone(ZoneOffset.systemDefault()).toInstant()); + @Before + public void before() throws Exception { + encoder = inject(new H02ProtocolEncoder(null)); + } + @Test public void testAlarmArmEncode() { diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java index 1cb273c2b..6f9c8250a 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class HuabaoProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new HuabaoProtocolEncoder(null); + var encoder = inject(new HuabaoProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java index 5302709fc..195fc4258 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 { - var encoder = new ItsProtocolEncoder(null); + var encoder = inject(new ItsProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java index 287d05fca..468083f35 100644 --- a/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class KhdProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new KhdProtocolEncoder(null); + var encoder = inject(new KhdProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java index 9c50d972a..5b72f6f1f 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 { - var encoder = new MeiligaoProtocolEncoder(null); + var encoder = inject(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 64fc7e17b..cc8847db2 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class MeitrackProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new MeitrackProtocolEncoder(null); + var encoder = inject(new MeitrackProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java index 652490b72..502f8e8bf 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 { - var encoder = new MiniFinderProtocolEncoder(null); + var encoder = inject(new MiniFinderProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java index 76486d024..d1b28525c 100644 --- a/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class NoranProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new NoranProtocolEncoder(null); + var encoder = inject(new NoranProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/PortmanProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/PortmanProtocolEncoderTest.java index 61f6c4a4e..b4c334a0c 100644 --- a/src/test/java/org/traccar/protocol/PortmanProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/PortmanProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class PortmanProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeEngineStop() { + public void testEncodeEngineStop() throws Exception { - var encoder = new PortmanProtocolEncoder(null); + var encoder = inject(new PortmanProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -22,9 +22,9 @@ public class PortmanProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeEngineResume() { + public void testEncodeEngineResume() throws Exception { - var encoder = new PortmanProtocolEncoder(null); + var encoder = inject(new PortmanProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java index 403c89e9e..d3218d4a8 100644 --- a/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class PretraceProtocolEncoderTest extends ProtocolTest { @Test public void testEncodePositionPeriodic() throws Exception { - var encoder = new PretraceProtocolEncoder(null); + var encoder = inject(new PretraceProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -25,7 +25,7 @@ public class PretraceProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeCustom() throws Exception { - var encoder = new PretraceProtocolEncoder(null); + var encoder = inject(new PretraceProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/PstProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/PstProtocolEncoderTest.java index abcfa29ec..6c3ff71b6 100644 --- a/src/test/java/org/traccar/protocol/PstProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/PstProtocolEncoderTest.java @@ -7,9 +7,9 @@ import org.traccar.model.Command; public class PstProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeEngineStop() { + public void testEncodeEngineStop() throws Exception { - var encoder = new PstProtocolEncoder(null); + var encoder = inject(new PstProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -20,9 +20,9 @@ public class PstProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeEngineResume() { + public void testEncodeEngineResume() throws Exception { - var encoder = new PstProtocolEncoder(null); + var encoder = inject(new PstProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java index 62b83c61c..c97093e26 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 { - var encoder = new Pt502ProtocolEncoder(null); + var encoder = inject(new Pt502ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -25,7 +25,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeOutputControl() throws Exception { - var encoder = new Pt502ProtocolEncoder(null); + var encoder = inject(new Pt502ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -40,7 +40,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { @Test public void testEncodeTimezone() throws Exception { - var encoder = new Pt502ProtocolEncoder(null); + var encoder = inject(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 { - var encoder = new Pt502ProtocolEncoder(null); + var encoder = inject(new Pt502ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java index 409cd4da5..0c4fc6767 100644 --- a/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class RuptelaProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new RuptelaProtocolEncoder(null); + var encoder = inject(new RuptelaProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/StartekProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolEncoderTest.java index 7eeb19edf..f04d0cb67 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class StartekProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeEngineStop() { + public void testEncodeEngineStop() throws Exception { - var encoder = new StartekProtocolEncoder(null); + var encoder = inject(new StartekProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java index 1d17ee5d5..b2d7c57a2 100644 --- a/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class T800xProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new T800xProtocolEncoder(null); + var encoder = inject(new T800xProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java index 008a2b9dd..d7e1149aa 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class TeltonikaProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new TeltonikaProtocolEncoder(null); + var encoder = inject(new TeltonikaProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java index d507f3c4f..359e432c7 100644 --- a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class Tk103ProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodeOutputControl() { + public void testEncodeOutputControl() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -23,9 +23,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeEngineStop() { + public void testEncodeEngineStop() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -36,9 +36,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionSingle() { + public void testEncodePositionSingle() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -49,9 +49,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionPeriodic() { + public void testEncodePositionPeriodic() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -63,9 +63,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionStop() { + public void testEncodePositionStop() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -76,9 +76,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeGetVersion() { + public void testEncodeGetVersion() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -89,9 +89,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeRebootDevice() { + public void testEncodeRebootDevice() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -102,9 +102,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeSetOdometer() { + public void testEncodeSetOdometer() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -115,9 +115,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionSingleAlternative() { + public void testEncodePositionSingleAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -128,9 +128,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionPeriodicAlternative() { + public void testEncodePositionPeriodicAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -141,9 +141,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodePositionStopAlternative() { + public void testEncodePositionStopAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -154,9 +154,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeGetVersionAlternative() { + public void testEncodeGetVersionAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -167,9 +167,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeRebootDeviceAlternative() { + public void testEncodeRebootDeviceAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -180,9 +180,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeIdentificationAlternative() { + public void testEncodeIdentificationAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -193,9 +193,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeSosOnAlternative() { + public void testEncodeSosOnAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -207,9 +207,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeSosOffAlternative() { + public void testEncodeSosOffAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -221,9 +221,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeCustom() { + public void testEncodeCustom() throws Exception { - var encoder = new Tk103ProtocolEncoder(null); + var encoder = inject(new Tk103ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -235,9 +235,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeCustomAlternative() { + public void testEncodeCustomAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -249,9 +249,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeSetConnectionAlternative() { + public void testEncodeSetConnectionAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); @@ -264,9 +264,9 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeSosNumberAlternative() { + public void testEncodeSosNumberAlternative() throws Exception { - var encoder = new Tk103ProtocolEncoder(null, true); + var encoder = inject(new Tk103ProtocolEncoder(null, true)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java index d3ff13941..a69f389ac 100644 --- a/src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/TopinProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class TopinProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new TopinProtocolEncoder(null); + var encoder = inject(new TopinProtocolEncoder(null)); 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 a4fca2d9e..97a044b51 100644 --- a/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class TotemProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new TotemProtocolEncoder(null); + var encoder = inject(new TotemProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(2); @@ -25,7 +25,7 @@ public class TotemProtocolEncoderTest extends ProtocolTest { @Test public void testSmsEncode() throws Exception { - var encoder = new TotemProtocolSmsEncoder(null); + var encoder = inject(new TotemProtocolSmsEncoder(null)); Command command = new Command(); command.setDeviceId(2); diff --git a/src/test/java/org/traccar/protocol/UlbotechProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/UlbotechProtocolEncoderTest.java index 288f8dc70..50e9321ce 100644 --- a/src/test/java/org/traccar/protocol/UlbotechProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/UlbotechProtocolEncoderTest.java @@ -7,9 +7,9 @@ import org.traccar.model.Command; public class UlbotechProtocolEncoderTest extends ProtocolTest { @Test - public void testEncode() { + public void testEncode() throws Exception { - var encoder = new UlbotechProtocolEncoder(null); + var encoder = inject(new UlbotechProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java index bcfc8df41..c83c103c3 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java @@ -9,7 +9,7 @@ public class WatchProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new WatchProtocolEncoder(null); + var encoder = inject(new WatchProtocolEncoder(null)); Command command; @@ -58,9 +58,9 @@ public class WatchProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeTimezone() { + public void testEncodeTimezone() throws Exception { - var encoder = new WatchProtocolEncoder(null); + var encoder = inject(new WatchProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java index ed0af844e..f482871dd 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 { - var encoder = new WondexProtocolEncoder(null); + var encoder = inject(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 4f01aa72b..76e2f960d 100644 --- a/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java @@ -11,7 +11,7 @@ public class XirgoProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - var encoder = new XirgoProtocolEncoder(null); + var encoder = inject(new XirgoProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); diff --git a/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java index 357da8f7b..a66efecc2 100644 --- a/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java @@ -9,9 +9,9 @@ import static org.junit.Assert.assertEquals; public class Xrb28ProtocolEncoderTest extends ProtocolTest { @Test - public void testEncodePositionPeriodic() { + public void testEncodePositionPeriodic() throws Exception { - var encoder = new Xrb28ProtocolEncoder(null); + var encoder = inject(new Xrb28ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); @@ -23,9 +23,9 @@ public class Xrb28ProtocolEncoderTest extends ProtocolTest { } @Test - public void testEncodeCustom() { + public void testEncodeCustom() throws Exception { - var encoder = new Xrb28ProtocolEncoder(null); + var encoder = inject(new Xrb28ProtocolEncoder(null)); Command command = new Command(); command.setDeviceId(1); -- cgit v1.2.3 From 85f04c6d30e11d8b748ea2b431dbeffce1126a65 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 14:59:09 -0700 Subject: Remove test identity manager --- src/main/java/org/traccar/reports/ReportUtils.java | 27 ++++---- src/test/java/org/traccar/BaseTest.java | 6 -- src/test/java/org/traccar/TestIdentityManager.java | 77 ---------------------- src/test/java/org/traccar/WebDataHandlerTest.java | 15 ++++- .../handler/events/AlertEventHandlerTest.java | 6 +- .../handler/events/IgnitionEventHandlerTest.java | 5 +- .../java/org/traccar/reports/ReportUtilsTest.java | 40 +++++++---- 7 files changed, 62 insertions(+), 114 deletions(-) delete mode 100644 src/test/java/org/traccar/TestIdentityManager.java diff --git a/src/main/java/org/traccar/reports/ReportUtils.java b/src/main/java/org/traccar/reports/ReportUtils.java index 23646c4d6..dd1ef478f 100644 --- a/src/main/java/org/traccar/reports/ReportUtils.java +++ b/src/main/java/org/traccar/reports/ReportUtils.java @@ -171,7 +171,8 @@ public final class ReportUtils { } private static TripReport calculateTrip( - ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer) { Position startTrip = positions.get(startIndex); Position endTrip = positions.get(endIndex); @@ -189,7 +190,7 @@ public final class ReportUtils { long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); trip.setDeviceId(deviceId); - trip.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); + trip.setDeviceName(identityManager.getById(deviceId).getName()); trip.setStartPositionId(startTrip.getId()); trip.setStartLat(startTrip.getLatitude()); @@ -238,7 +239,8 @@ public final class ReportUtils { } private static StopReport calculateStop( - ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer) { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); @@ -247,7 +249,7 @@ public final class ReportUtils { long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); - stop.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); + stop.setDeviceName(identityManager.getById(deviceId).getName()); stop.setPositionId(startStop.getId()); stop.setLatitude(startStop.getLatitude()); @@ -286,12 +288,13 @@ public final class ReportUtils { } private static T calculateTripOrStop( - ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { if (reportClass.equals(TripReport.class)) { - return (T) calculateTrip(positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateTrip(identityManager, positions, startIndex, endIndex, ignoreOdometer); } else { - return (T) calculateStop(positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); } } @@ -351,15 +354,15 @@ public final class ReportUtils { } if (startEventIndex != -1 && startNoEventIndex != -1 && event != null && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop(positions, startEventIndex, startNoEventIndex, - ignoreOdometer, reportClass)); + result.add(calculateTripOrStop(identityManager, positions, + startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); startEventIndex = -1; } } if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - result.add(calculateTripOrStop(positions, startEventIndex, - startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, - ignoreOdometer, reportClass)); + result.add(calculateTripOrStop(identityManager, positions, + startEventIndex, startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, + ignoreOdometer, reportClass)); } } diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 2eedd4bd8..0f6c55857 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,7 +1,5 @@ package org.traccar; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; import org.traccar.config.Config; import org.traccar.database.ConnectionManager; import org.traccar.database.IdentityManager; @@ -18,10 +16,6 @@ import static org.mockito.Mockito.when; public class BaseTest { - static { - Context.init(new TestIdentityManager()); - } - protected T inject(T decoder) throws Exception { decoder.setConfig(new Config()); var device = mock(Device.class); diff --git a/src/test/java/org/traccar/TestIdentityManager.java b/src/test/java/org/traccar/TestIdentityManager.java deleted file mode 100644 index 68d98db9a..000000000 --- a/src/test/java/org/traccar/TestIdentityManager.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.traccar; - -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Position; - -public final class TestIdentityManager implements IdentityManager { - - private static Device createDevice() { - Device device = new Device(); - device.setId(1); - device.setName("test"); - device.setUniqueId("123456789012345"); - return device; - } - - @Override - public long addUnknownDevice(String uniqueId) { - return 1; - } - - @Override - public Device getById(long id) { - return createDevice(); - } - - @Override - public Device getByUniqueId(String uniqueId) { - return createDevice(); - } - - @Override - public String getDevicePassword(long id, String protocol, String defaultPassword) { - return defaultPassword; - } - - @Override - public Position getLastPosition(long deviceId) { - return null; - } - - @Override - public boolean isLatestPosition(Position position) { - return true; - } - - @Override - public boolean lookupAttributeBoolean( - long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig) { - return defaultValue; - } - - @Override - public String lookupAttributeString( - long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig) { - return defaultValue; - } - - @Override - public int lookupAttributeInteger( - long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig) { - return defaultValue; - } - - @Override - public long lookupAttributeLong( - long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig) { - return defaultValue; - } - - @Override - public double lookupAttributeDouble( - long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig) { - return defaultValue; - } - -} diff --git a/src/test/java/org/traccar/WebDataHandlerTest.java b/src/test/java/org/traccar/WebDataHandlerTest.java index cfbd71f23..aaec9f530 100644 --- a/src/test/java/org/traccar/WebDataHandlerTest.java +++ b/src/test/java/org/traccar/WebDataHandlerTest.java @@ -3,9 +3,14 @@ package org.traccar; import org.junit.Test; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; import org.traccar.model.Position; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class WebDataHandlerTest extends ProtocolTest { @@ -17,7 +22,15 @@ public class WebDataHandlerTest extends ProtocolTest { Position position = position("2016-01-01 01:02:03.000", true, 20, 30); - WebDataHandler handler = new WebDataHandler(config, Context.getIdentityManager(), null, null); + var device = mock(Device.class); + when(device.getId()).thenReturn(1L); + when(device.getName()).thenReturn("test"); + when(device.getUniqueId()).thenReturn("123456789012345"); + when(device.getStatus()).thenReturn(Device.STATUS_ONLINE); + var identityManager = mock(IdentityManager.class); + when(identityManager.getById(anyLong())).thenReturn(device); + + WebDataHandler handler = new WebDataHandler(config, identityManager, null, null); assertEquals( "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", diff --git a/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java b/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java index 3f0823245..4934695ad 100644 --- a/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java @@ -2,13 +2,14 @@ package org.traccar.handler.events; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; import java.util.Map; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.TestIdentityManager; import org.traccar.config.Config; +import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; @@ -17,7 +18,7 @@ public class AlertEventHandlerTest extends BaseTest { @Test public void testAlertEventHandler() { - AlertEventHandler alertEventHandler = new AlertEventHandler(new Config(), new TestIdentityManager()); + AlertEventHandler alertEventHandler = new AlertEventHandler(new Config(), mock(IdentityManager.class)); Position position = new Position(); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); @@ -25,6 +26,7 @@ public class AlertEventHandlerTest extends BaseTest { assertNotNull(events); Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_ALARM, event.getType()); + } } diff --git a/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java index dade20fb8..f568b6a74 100644 --- a/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java @@ -1,12 +1,13 @@ package org.traccar.handler.events; import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; import java.util.Map; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.TestIdentityManager; +import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; @@ -15,7 +16,7 @@ public class IgnitionEventHandlerTest extends BaseTest { @Test public void testIgnitionEventHandler() { - IgnitionEventHandler ignitionEventHandler = new IgnitionEventHandler(new TestIdentityManager()); + IgnitionEventHandler ignitionEventHandler = new IgnitionEventHandler(mock(IdentityManager.class)); Position position = new Position(); position.set(Position.KEY_IGNITION, true); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index deb17ddd2..b27104f76 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -4,6 +4,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.text.DateFormat; import java.text.ParseException; @@ -17,7 +20,8 @@ import java.util.TimeZone; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.TestIdentityManager; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; @@ -43,6 +47,14 @@ public class ReportUtilsTest extends BaseTest { return position; } + private IdentityManager mockIdentityManager() { + var device = mock(Device.class); + when(device.getName()).thenReturn("test"); + var identityManager = mock(IdentityManager.class); + when(identityManager.getById(anyLong())).thenReturn(device); + return identityManager; + } + @Test public void testCalculateDistance() { Position startPosition = new Position(); @@ -81,7 +93,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -96,7 +108,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -135,7 +147,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -150,7 +162,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); trips = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -165,7 +177,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -206,7 +218,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -221,7 +233,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -256,7 +268,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -283,7 +295,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -310,7 +322,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -337,7 +349,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -360,7 +372,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -375,7 +387,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(600, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - new TestIdentityManager(), null, data, tripsConfig, false, StopReport.class); + mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 39487ee68a8949f1c2575daec5ded14cfc14cedb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 15:03:18 -0700 Subject: Fix tests --- .../java/org/traccar/protocol/At2000ProtocolDecoderTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/org/traccar/protocol/At2000ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/At2000ProtocolDecoderTest.java index 9e2f180d2..8c32289f1 100644 --- a/src/test/java/org/traccar/protocol/At2000ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/At2000ProtocolDecoderTest.java @@ -14,7 +14,7 @@ public class At2000ProtocolDecoderTest extends ProtocolTest { At2000ProtocolDecoder decoder; - decoder = new At2000ProtocolDecoder(null); + decoder = inject(new At2000ProtocolDecoder(null)); verifyNull(decoder, binary( "01012f00000000000000000000000000003335373435343037313632373539388b57ec3a6ec7e3310a1ceb0a70fd751b8f2e7be6df1d6dcd80129f66fff0ea1c")); @@ -22,7 +22,7 @@ public class At2000ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "89000000000000000000000000000000")); - decoder = new At2000ProtocolDecoder(null); + decoder = inject(new At2000ProtocolDecoder(null)); verifyNull(decoder, binary( "01012f0000000000000000000000000000333537343534303731363036313936ddf189075add9a32d97b54073025963e65849a3a59940d05fd8db655fc84bc6d")); @@ -30,7 +30,7 @@ public class At2000ProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "893b01000000000000000000000000003b40bcdab6387d829146701d8cb53daaa87b84d24b40cb24fd86da5d3f5f02b0f6f603c43c5a513418a0b2bdcaba603dbe737687cfe9082c57668eb6789d2b029a35aeac6a609558b96de5d7ad37917c902efc878ca9aff474f9d5d2417191285b8d5749bd3ffa86cc99096ce24c1f6ac350ae9adf3d5c788f80b4e3d3dc2dbb8abc1414ea1b52fdb55b2bb8af223ec528245f99d451b715e5774c5397db645d9ae441e645f8dae70230b728e81f51240868712d6f426fd694dbad8026fcf487c268939f04593ad86391cc829b1a1bdac8804ff7507544a69dc0b1b3927d7344e8a5b26fa56825283b3e476330b36d15011e1647ebd9f2ef71844ed32c0dc050457bfbd79160e6d1d8cda00a0927c8957631770e98eb20735aa46b0b18502baf4c45d2623ee51a4320cf3018010e7bbf8bc0dd79eb28e88b727ea67e980b8a91")); - decoder = new At2000ProtocolDecoder(null); + decoder = inject(new At2000ProtocolDecoder(null)); verifyNull(decoder, binary( "01012f000000000000000000000000000033353734353430373136303631393637f5441a9862260117858237fe3160388490f0df7d46c09112ee087235a92101")); @@ -38,7 +38,7 @@ public class At2000ProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "89043203000000000000000000000000d01ff1df1b56ba9185bb741ddc253f3cee093b1f8193100cd95777b5288a6f29d1b343a952f882ce8825679f7e27ad88ed7898bff92f716acadfc3c17fa8c1a6b9d0934e8f042433a183776c06c1acd73efb4b9f19030debb4dceb161fb3e6630757d25c3e995b7cf5f446318dcc1677eb215d1af49f11cd7300598bcdc40cc25466ed2391d836c782e44bc04a332e902b2b34f5597a542af4ca670cdfc18d87ce2a225c3e6f2f32359d4914c6df09aa5ee306c229260d4a56da53f93398bc8a6e77095305ee214cf605de20d3876a993fb810486f75bcd514c12442bf4dc3fbe7963b20d5100b5ecff1c1aef4c4b3736a04e245d50f538327db21d55270b279db5ac5a9658876bae3d9b5026b8975bb2bf4d100b8492760d66ae31f27bf9c525c2d794860eabca9c788b91152dbce79f336daaf6a7a9547bf1dd8e3334c891f4548fd6d112ebf45125c2a8abd3a786ebbcfdd03101b524bbf465f14a9a424305ce7de56ffca85b4657fc8c03e4349c0ca6be64d1cf595ee91f8173678ef2267dae54dd00028450c48d9b74c925af0f245d409d8773238dce5832747587f53a12155869c1d464eb0630f94cf8dceb76aa39995411d4ce7743b1501692425afec498535526067e79f568b7f71ee47d8b4929118d57b13d56cdbfd26582d579dee")); - decoder = new At2000ProtocolDecoder(null); + decoder = inject(new At2000ProtocolDecoder(null)); verifyNull(decoder, binary( "01012f0000000000000000000000000000333537343534303731363035353033dd529a1eb5df9f3b6d320b38250e03306692957e8c2127d8e381a717f639b4c9")); @@ -46,7 +46,7 @@ public class At2000ProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "89898701000000000000000000000000ae99e38f13d44f536769eb4930a6826dfebe5b98a6048941e89b17c9cdcb276be4af7c0d188d07c90d6e94aa9efcb465fe7aeaff4d85caf837483b4e9b32fbbacfbc4e175eebf57a27f552a64fc3419565d2dfbea668511a08d5a526342fad0e93b20c4449ad8defab4a9ac68cf7dad86971eb2cd96810d9d6a9c56e07fd90e4c28cfc53a069b63efe37a0523a69b607a2dc011ba17b177c5332c04be1faeeabed24539b3b790fa8a8610ab3633e0140ed79690fcae9dea43c7daad780d95a511d8f4875e621bcfe7516a03b80eb3c473ffd4bc1eda298dfa7d994a2cfeaa5d24c190d52d72fd90975a2e6f9ed3b95017133952262f91787c46839738a80c333dc53ee4d8afe75315d801efe17bc7309f30cfce64906bf70e6844c835781cbb64b49e9315ca3c2cd39d00a03cc7178a4ebc5df230dcdfd44ec588791d488f96bb6ff4007a753f552bda4d1766632aa3ec5eb38feb23ed6efb8f382a7f22b70adc9cb533c09bf749190c36d63b572c1acfc3a59138d51273835ab13c4689df01e3d2c2dd1829e00aac5c56b5d51e60d6731833f82c7464d88df663ca28a20eedeecb60f3704ae78281838caa116184e414db459768321bbfa1e83ad59fe168eb81f3b41cfe0e39c8aa78cbbe5825620bf053a1cb62e04d4cdf17ca2dc9305d47c")); - decoder = new At2000ProtocolDecoder(null); + decoder = inject(new At2000ProtocolDecoder(null)); verifyNull(decoder, binary( "01012f00000000000000000000000000003335363137333036343430373439320fad981997ae8e031fe10c0ea7641903ca32c0331df467233d2a9cd886fbeef8")); -- cgit v1.2.3 From 00b91d01d89a32710baa9e580bdf581dae7aa711 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 16:44:20 -0700 Subject: Combine session related classes --- src/main/java/org/traccar/BaseProtocolDecoder.java | 3 +- src/main/java/org/traccar/Context.java | 2 +- src/main/java/org/traccar/DeviceSession.java | 42 ---- src/main/java/org/traccar/MainModule.java | 2 +- src/main/java/org/traccar/api/AsyncSocket.java | 2 +- .../java/org/traccar/database/ActiveDevice.java | 58 ------ .../java/org/traccar/database/CommandsManager.java | 1 + .../org/traccar/database/ConnectionManager.java | 219 --------------------- .../java/org/traccar/database/DeviceManager.java | 2 +- .../handler/events/GeofenceEventHandler.java | 2 +- .../traccar/handler/events/MotionEventHandler.java | 2 +- .../handler/events/OverspeedEventHandler.java | 2 +- src/main/java/org/traccar/model/DeviceState.java | 71 ------- .../org/traccar/protocol/AdmProtocolDecoder.java | 2 +- .../org/traccar/protocol/AisProtocolDecoder.java | 2 +- .../traccar/protocol/AlematicsProtocolDecoder.java | 2 +- .../traccar/protocol/AnytrekProtocolDecoder.java | 2 +- .../org/traccar/protocol/ApelProtocolDecoder.java | 2 +- .../traccar/protocol/AplicomProtocolDecoder.java | 2 +- .../traccar/protocol/AppelloProtocolDecoder.java | 2 +- .../traccar/protocol/AquilaProtocolDecoder.java | 2 +- .../traccar/protocol/Ardi01ProtocolDecoder.java | 2 +- .../traccar/protocol/ArknavProtocolDecoder.java | 2 +- .../traccar/protocol/ArknavX8ProtocolDecoder.java | 2 +- .../traccar/protocol/ArmoliProtocolDecoder.java | 2 +- .../protocol/ArnaviBinaryProtocolDecoder.java | 2 +- .../protocol/ArnaviTextProtocolDecoder.java | 2 +- .../org/traccar/protocol/AstraProtocolDecoder.java | 2 +- .../traccar/protocol/At2000ProtocolDecoder.java | 2 +- .../traccar/protocol/AtrackProtocolDecoder.java | 2 +- .../org/traccar/protocol/AuroProtocolDecoder.java | 2 +- .../traccar/protocol/AustinNbProtocolDecoder.java | 2 +- .../traccar/protocol/AutoFonProtocolDecoder.java | 2 +- .../traccar/protocol/AutoGradeProtocolDecoder.java | 2 +- .../traccar/protocol/AutoTrackProtocolDecoder.java | 2 +- .../org/traccar/protocol/AvemaProtocolDecoder.java | 2 +- .../traccar/protocol/Avl301ProtocolDecoder.java | 2 +- .../org/traccar/protocol/B2316ProtocolDecoder.java | 2 +- .../org/traccar/protocol/BceProtocolDecoder.java | 2 +- .../traccar/protocol/BlackKiteProtocolDecoder.java | 2 +- .../org/traccar/protocol/BlueProtocolDecoder.java | 2 +- .../org/traccar/protocol/BoxProtocolDecoder.java | 2 +- .../traccar/protocol/C2stekProtocolDecoder.java | 2 +- .../traccar/protocol/CalAmpProtocolDecoder.java | 2 +- .../traccar/protocol/CarTrackProtocolDecoder.java | 2 +- .../traccar/protocol/CarcellProtocolDecoder.java | 2 +- .../traccar/protocol/CarscopProtocolDecoder.java | 2 +- .../traccar/protocol/CastelProtocolDecoder.java | 2 +- .../traccar/protocol/CautelaProtocolDecoder.java | 2 +- .../protocol/CellocatorProtocolDecoder.java | 2 +- .../traccar/protocol/CguardProtocolDecoder.java | 2 +- .../traccar/protocol/CityeasyProtocolDecoder.java | 2 +- .../protocol/ContinentalProtocolDecoder.java | 2 +- .../protocol/CradlepointProtocolDecoder.java | 2 +- .../traccar/protocol/DingtekProtocolDecoder.java | 2 +- .../org/traccar/protocol/DishaProtocolDecoder.java | 2 +- .../traccar/protocol/DmtHttpProtocolDecoder.java | 2 +- .../org/traccar/protocol/DmtProtocolDecoder.java | 2 +- .../traccar/protocol/DolphinProtocolDecoder.java | 2 +- .../org/traccar/protocol/Dsf22ProtocolDecoder.java | 2 +- .../traccar/protocol/DualcamProtocolDecoder.java | 2 +- .../org/traccar/protocol/DwayProtocolDecoder.java | 2 +- .../traccar/protocol/EasyTrackProtocolDecoder.java | 2 +- .../traccar/protocol/EelinkProtocolDecoder.java | 2 +- .../org/traccar/protocol/EgtsProtocolDecoder.java | 2 +- .../traccar/protocol/EnforaProtocolDecoder.java | 2 +- .../org/traccar/protocol/EnnfuProtocolDecoder.java | 2 +- .../traccar/protocol/EnvotechProtocolDecoder.java | 2 +- .../org/traccar/protocol/EsealProtocolDecoder.java | 2 +- .../org/traccar/protocol/EskyProtocolDecoder.java | 2 +- .../protocol/ExtremTracProtocolDecoder.java | 2 +- .../traccar/protocol/FifotrackProtocolDecoder.java | 2 +- .../traccar/protocol/FlespiProtocolDecoder.java | 2 +- .../traccar/protocol/FlexApiProtocolDecoder.java | 2 +- .../traccar/protocol/FlexCommProtocolDecoder.java | 2 +- .../protocol/FlexibleReportProtocolDecoder.java | 2 +- .../traccar/protocol/FlextrackProtocolDecoder.java | 2 +- .../org/traccar/protocol/FoxProtocolDecoder.java | 2 +- .../traccar/protocol/FreedomProtocolDecoder.java | 2 +- .../protocol/FreematicsProtocolDecoder.java | 2 +- .../traccar/protocol/FutureWayProtocolDecoder.java | 2 +- .../traccar/protocol/GalileoProtocolDecoder.java | 2 +- .../org/traccar/protocol/GatorProtocolDecoder.java | 2 +- .../org/traccar/protocol/GenxProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gl100ProtocolDecoder.java | 2 +- .../protocol/Gl200BinaryProtocolDecoder.java | 2 +- .../traccar/protocol/Gl200TextProtocolDecoder.java | 2 +- .../traccar/protocol/GlobalSatProtocolDecoder.java | 2 +- .../protocol/GlobalstarProtocolDecoder.java | 2 +- .../org/traccar/protocol/GnxProtocolDecoder.java | 2 +- .../traccar/protocol/GoSafeProtocolDecoder.java | 2 +- .../org/traccar/protocol/GotopProtocolDecoder.java | 2 +- .../traccar/protocol/Gps056ProtocolDecoder.java | 2 +- .../traccar/protocol/Gps103ProtocolDecoder.java | 2 +- .../traccar/protocol/GpsGateProtocolDecoder.java | 2 +- .../traccar/protocol/GpsMarkerProtocolDecoder.java | 2 +- .../traccar/protocol/GpsmtaProtocolDecoder.java | 2 +- .../traccar/protocol/GranitProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gs100ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gt02ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gt30ProtocolDecoder.java | 2 +- .../org/traccar/protocol/H02ProtocolDecoder.java | 2 +- .../traccar/protocol/HaicomProtocolDecoder.java | 2 +- .../traccar/protocol/HomtecsProtocolDecoder.java | 2 +- .../org/traccar/protocol/HoopoProtocolDecoder.java | 2 +- .../traccar/protocol/HuaShengProtocolDecoder.java | 2 +- .../traccar/protocol/HuabaoProtocolDecoder.java | 2 +- .../traccar/protocol/HunterProProtocolDecoder.java | 2 +- .../org/traccar/protocol/IdplProtocolDecoder.java | 2 +- .../protocol/IntellitracProtocolDecoder.java | 2 +- .../org/traccar/protocol/IotmProtocolDecoder.java | 2 +- .../org/traccar/protocol/ItsProtocolDecoder.java | 2 +- .../traccar/protocol/Ivt401ProtocolDecoder.java | 2 +- .../org/traccar/protocol/JidoProtocolDecoder.java | 2 +- .../traccar/protocol/JpKorjarProtocolDecoder.java | 2 +- .../org/traccar/protocol/Jt600ProtocolDecoder.java | 2 +- .../org/traccar/protocol/KenjiProtocolDecoder.java | 2 +- .../org/traccar/protocol/KhdProtocolDecoder.java | 2 +- .../org/traccar/protocol/L100ProtocolDecoder.java | 2 +- .../org/traccar/protocol/LacakProtocolDecoder.java | 2 +- .../traccar/protocol/LaipacProtocolDecoder.java | 2 +- .../traccar/protocol/LeafSpyProtocolDecoder.java | 2 +- .../org/traccar/protocol/M2cProtocolDecoder.java | 2 +- .../org/traccar/protocol/M2mProtocolDecoder.java | 2 +- .../traccar/protocol/MaestroProtocolDecoder.java | 2 +- .../traccar/protocol/ManPowerProtocolDecoder.java | 2 +- .../traccar/protocol/Mavlink2ProtocolDecoder.java | 2 +- .../traccar/protocol/MegastekProtocolDecoder.java | 2 +- .../traccar/protocol/MeiligaoProtocolDecoder.java | 2 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 2 +- .../traccar/protocol/MictrackProtocolDecoder.java | 2 +- .../traccar/protocol/MilesmateProtocolDecoder.java | 2 +- .../protocol/MiniFinderProtocolDecoder.java | 2 +- .../protocol/Minifinder2ProtocolDecoder.java | 2 +- .../traccar/protocol/MobilogixProtocolDecoder.java | 2 +- .../traccar/protocol/MoovboxProtocolDecoder.java | 2 +- .../org/traccar/protocol/MotorProtocolDecoder.java | 2 +- .../org/traccar/protocol/Mta6ProtocolDecoder.java | 2 +- .../org/traccar/protocol/MtxProtocolDecoder.java | 2 +- .../org/traccar/protocol/MxtProtocolDecoder.java | 2 +- .../traccar/protocol/NavigilProtocolDecoder.java | 2 +- .../org/traccar/protocol/NavisProtocolDecoder.java | 2 +- .../traccar/protocol/NavisetProtocolDecoder.java | 2 +- .../protocol/NavtelecomProtocolDecoder.java | 2 +- .../org/traccar/protocol/NeosProtocolDecoder.java | 2 +- .../org/traccar/protocol/NetProtocolDecoder.java | 2 +- .../org/traccar/protocol/NiotProtocolDecoder.java | 2 +- .../org/traccar/protocol/NoranProtocolDecoder.java | 2 +- .../org/traccar/protocol/NvsProtocolDecoder.java | 2 +- .../traccar/protocol/NyitechProtocolDecoder.java | 2 +- .../traccar/protocol/ObdDongleProtocolDecoder.java | 2 +- .../org/traccar/protocol/OigoProtocolDecoder.java | 2 +- .../org/traccar/protocol/OkoProtocolDecoder.java | 2 +- .../traccar/protocol/OmnicommProtocolDecoder.java | 2 +- .../traccar/protocol/OpenGtsProtocolDecoder.java | 2 +- .../traccar/protocol/OrbcommProtocolDecoder.java | 2 +- .../org/traccar/protocol/OrionProtocolDecoder.java | 2 +- .../traccar/protocol/OsmAndProtocolDecoder.java | 2 +- .../traccar/protocol/OutsafeProtocolDecoder.java | 2 +- .../traccar/protocol/OwnTracksProtocolDecoder.java | 2 +- .../protocol/PacificTrackProtocolDecoder.java | 2 +- .../traccar/protocol/PathAwayProtocolDecoder.java | 2 +- .../traccar/protocol/PiligrimProtocolDecoder.java | 2 +- .../traccar/protocol/PluginProtocolDecoder.java | 2 +- .../org/traccar/protocol/PolteProtocolDecoder.java | 2 +- .../traccar/protocol/PortmanProtocolDecoder.java | 2 +- .../traccar/protocol/PretraceProtocolDecoder.java | 2 +- .../traccar/protocol/PricolProtocolDecoder.java | 2 +- .../traccar/protocol/ProgressProtocolDecoder.java | 2 +- .../org/traccar/protocol/PstProtocolDecoder.java | 2 +- .../org/traccar/protocol/Pt215ProtocolDecoder.java | 2 +- .../traccar/protocol/Pt3000ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Pt502ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Pt60ProtocolDecoder.java | 2 +- .../org/traccar/protocol/R12wProtocolDecoder.java | 2 +- .../protocol/RaceDynamicsProtocolDecoder.java | 2 +- .../org/traccar/protocol/RadarProtocolDecoder.java | 2 +- .../traccar/protocol/RaveonProtocolDecoder.java | 2 +- .../traccar/protocol/RecodaProtocolDecoder.java | 2 +- .../protocol/RetranslatorProtocolDecoder.java | 2 +- .../org/traccar/protocol/RitiProtocolDecoder.java | 2 +- .../traccar/protocol/RoboTrackProtocolDecoder.java | 2 +- .../org/traccar/protocol/RstProtocolDecoder.java | 2 +- .../traccar/protocol/RuptelaProtocolDecoder.java | 2 +- .../org/traccar/protocol/S168ProtocolDecoder.java | 2 +- .../traccar/protocol/SabertekProtocolDecoder.java | 2 +- .../org/traccar/protocol/SanavProtocolDecoder.java | 2 +- .../org/traccar/protocol/SanulProtocolDecoder.java | 2 +- .../traccar/protocol/SatsolProtocolDecoder.java | 2 +- .../traccar/protocol/SigfoxProtocolDecoder.java | 2 +- .../org/traccar/protocol/SiwiProtocolDecoder.java | 2 +- .../traccar/protocol/SkypatrolProtocolDecoder.java | 2 +- .../traccar/protocol/SmartSoleProtocolDecoder.java | 2 +- .../traccar/protocol/SmokeyProtocolDecoder.java | 2 +- .../protocol/SolarPoweredProtocolDecoder.java | 2 +- .../org/traccar/protocol/SpotProtocolDecoder.java | 2 +- .../traccar/protocol/StarLinkProtocolDecoder.java | 2 +- .../traccar/protocol/StarcomProtocolDecoder.java | 2 +- .../traccar/protocol/StartekProtocolDecoder.java | 2 +- .../org/traccar/protocol/StbProtocolDecoder.java | 2 +- .../traccar/protocol/Stl060ProtocolDecoder.java | 2 +- .../traccar/protocol/SuntechProtocolDecoder.java | 2 +- .../traccar/protocol/SupermateProtocolDecoder.java | 2 +- .../org/traccar/protocol/SviasProtocolDecoder.java | 2 +- .../traccar/protocol/SwiftechProtocolDecoder.java | 2 +- .../org/traccar/protocol/T55ProtocolDecoder.java | 2 +- .../org/traccar/protocol/T57ProtocolDecoder.java | 2 +- .../org/traccar/protocol/T800xProtocolDecoder.java | 2 +- .../org/traccar/protocol/TaipProtocolDecoder.java | 2 +- .../traccar/protocol/TechTltProtocolDecoder.java | 2 +- .../protocol/TechtoCruzProtocolDecoder.java | 2 +- .../org/traccar/protocol/TekProtocolDecoder.java | 2 +- .../traccar/protocol/TelemaxProtocolDecoder.java | 2 +- .../org/traccar/protocol/TelicProtocolDecoder.java | 2 +- .../traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- .../traccar/protocol/TeraTrackProtocolDecoder.java | 2 +- .../protocol/ThinkPowerProtocolDecoder.java | 2 +- .../traccar/protocol/ThinkRaceProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tk102ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tk103ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tlt2hProtocolDecoder.java | 2 +- .../org/traccar/protocol/TlvProtocolDecoder.java | 2 +- .../org/traccar/protocol/TmgProtocolDecoder.java | 2 +- .../protocol/TopflytechProtocolDecoder.java | 2 +- .../org/traccar/protocol/TopinProtocolDecoder.java | 2 +- .../org/traccar/protocol/TotemProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tr20ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Tr900ProtocolDecoder.java | 2 +- .../traccar/protocol/TrackboxProtocolDecoder.java | 2 +- .../traccar/protocol/TrakMateProtocolDecoder.java | 2 +- .../traccar/protocol/TramigoProtocolDecoder.java | 2 +- .../org/traccar/protocol/TrvProtocolDecoder.java | 2 +- .../traccar/protocol/Tt8850ProtocolDecoder.java | 2 +- .../org/traccar/protocol/TytanProtocolDecoder.java | 2 +- .../org/traccar/protocol/TzoneProtocolDecoder.java | 2 +- .../traccar/protocol/UlbotechProtocolDecoder.java | 2 +- .../org/traccar/protocol/UproProtocolDecoder.java | 2 +- .../org/traccar/protocol/UuxProtocolDecoder.java | 2 +- .../org/traccar/protocol/V680ProtocolDecoder.java | 2 +- .../traccar/protocol/VisiontekProtocolDecoder.java | 2 +- .../org/traccar/protocol/VnetProtocolDecoder.java | 2 +- .../org/traccar/protocol/Vt200ProtocolDecoder.java | 2 +- .../org/traccar/protocol/VtfmsProtocolDecoder.java | 2 +- .../org/traccar/protocol/WatchProtocolDecoder.java | 2 +- .../traccar/protocol/WialonProtocolDecoder.java | 2 +- .../org/traccar/protocol/WliProtocolDecoder.java | 2 +- .../traccar/protocol/WondexProtocolDecoder.java | 2 +- .../traccar/protocol/WristbandProtocolDecoder.java | 2 +- .../traccar/protocol/Xexun2ProtocolDecoder.java | 2 +- .../org/traccar/protocol/XexunProtocolDecoder.java | 2 +- .../org/traccar/protocol/XirgoProtocolDecoder.java | 2 +- .../org/traccar/protocol/Xrb28ProtocolDecoder.java | 2 +- .../org/traccar/protocol/Xt013ProtocolDecoder.java | 2 +- .../traccar/protocol/Xt2400ProtocolDecoder.java | 2 +- .../org/traccar/protocol/YwtProtocolDecoder.java | 2 +- src/main/java/org/traccar/reports/ReportUtils.java | 2 +- .../java/org/traccar/session/ActiveDevice.java | 58 ++++++ .../org/traccar/session/ConnectionManager.java | 218 ++++++++++++++++++++ .../java/org/traccar/session/DeviceSession.java | 42 ++++ src/main/java/org/traccar/session/DeviceState.java | 73 +++++++ src/test/java/org/traccar/BaseTest.java | 2 +- .../handler/events/MotionEventHandlerTest.java | 2 +- .../handler/events/OverspeedEventHandlerTest.java | 2 +- 264 files changed, 648 insertions(+), 645 deletions(-) delete mode 100644 src/main/java/org/traccar/DeviceSession.java delete mode 100644 src/main/java/org/traccar/database/ActiveDevice.java delete mode 100644 src/main/java/org/traccar/database/ConnectionManager.java delete mode 100644 src/main/java/org/traccar/model/DeviceState.java create mode 100644 src/main/java/org/traccar/session/ActiveDevice.java create mode 100644 src/main/java/org/traccar/session/ConnectionManager.java create mode 100644 src/main/java/org/traccar/session/DeviceSession.java create mode 100644 src/main/java/org/traccar/session/DeviceState.java diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 9a396bd64..3fc6e7697 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -25,7 +25,7 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.CommandsManager; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; @@ -33,6 +33,7 @@ import org.traccar.helper.UnitsConverter; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.DeviceSession; import java.net.InetSocketAddress; import java.net.SocketAddress; diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 237a34624..1faa4c9de 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -27,7 +27,7 @@ import org.traccar.database.AttributesManager; import org.traccar.database.BaseObjectManager; import org.traccar.database.CalendarManager; import org.traccar.database.CommandsManager; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.DriversManager; diff --git a/src/main/java/org/traccar/DeviceSession.java b/src/main/java/org/traccar/DeviceSession.java deleted file mode 100644 index 322381807..000000000 --- a/src/main/java/org/traccar/DeviceSession.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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; - -import java.util.TimeZone; - -public class DeviceSession { - - private final long deviceId; - - public DeviceSession(long deviceId) { - this.deviceId = deviceId; - } - - public long getDeviceId() { - return deviceId; - } - - private TimeZone timeZone; - - public void setTimeZone(TimeZone timeZone) { - this.timeZone = timeZone; - } - - public TimeZone getTimeZone() { - return timeZone; - } - -} diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 60b5854fd..43ca3ba77 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -26,7 +26,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.AttributesManager; import org.traccar.database.CalendarManager; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.GeofenceManager; diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java index b1853822d..b5902c4fb 100644 --- a/src/main/java/org/traccar/api/AsyncSocket.java +++ b/src/main/java/org/traccar/api/AsyncSocket.java @@ -21,7 +21,7 @@ import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/database/ActiveDevice.java b/src/main/java/org/traccar/database/ActiveDevice.java deleted file mode 100644 index c05d56ad2..000000000 --- a/src/main/java/org/traccar/database/ActiveDevice.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2015 - 2020 Anton Tananaev (anton@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.database; - -import io.netty.channel.Channel; -import io.netty.handler.codec.http.HttpRequestDecoder; -import org.traccar.BasePipelineFactory; -import org.traccar.Protocol; -import org.traccar.model.Command; - -import java.net.SocketAddress; - -public class ActiveDevice { - - private final long deviceId; - private final Protocol protocol; - private final Channel channel; - private final SocketAddress remoteAddress; - private final boolean supportsLiveCommands; - - public ActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - this.deviceId = deviceId; - this.protocol = protocol; - this.channel = channel; - this.remoteAddress = remoteAddress; - supportsLiveCommands = BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) == null; - } - - public Channel getChannel() { - return channel; - } - - public long getDeviceId() { - return deviceId; - } - - public boolean supportsLiveCommands() { - return supportsLiveCommands; - } - - public void sendCommand(Command command) { - protocol.sendDataCommand(channel, remoteAddress, command); - } - -} diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 843c89e82..3adf5d2e9 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -34,6 +34,7 @@ import org.traccar.Context; import org.traccar.model.Command; import org.traccar.model.Typed; import org.traccar.model.Position; +import org.traccar.session.ActiveDevice; public class CommandsManager extends ExtendedObjectManager { diff --git a/src/main/java/org/traccar/database/ConnectionManager.java b/src/main/java/org/traccar/database/ConnectionManager.java deleted file mode 100644 index f0e40f631..000000000 --- a/src/main/java/org/traccar/database/ConnectionManager.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2015 - 2022 Anton Tananaev (anton@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.database; - -import io.netty.channel.Channel; -import io.netty.util.Timeout; -import io.netty.util.Timer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.Protocol; -import org.traccar.config.Keys; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.handler.events.OverspeedEventHandler; -import org.traccar.model.Device; -import org.traccar.model.DeviceState; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.storage.StorageException; - -import java.net.SocketAddress; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; - -public class ConnectionManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); - - private final long deviceTimeout; - private final boolean updateDeviceState; - - private final Map activeDevices = new ConcurrentHashMap<>(); - private final Map> listeners = new ConcurrentHashMap<>(); - private final Map timeouts = new ConcurrentHashMap<>(); - - private final Timer timer; - - public ConnectionManager() { - deviceTimeout = Context.getConfig().getLong(Keys.STATUS_TIMEOUT) * 1000; - updateDeviceState = Context.getConfig().getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); - timer = Main.getInjector().getInstance(Timer.class); - } - - public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - activeDevices.put(deviceId, new ActiveDevice(deviceId, protocol, channel, remoteAddress)); - } - - public void removeActiveDevice(Channel channel) { - for (ActiveDevice activeDevice : activeDevices.values()) { - if (activeDevice.getChannel() == channel) { - updateDevice(activeDevice.getDeviceId(), Device.STATUS_OFFLINE, null); - activeDevices.remove(activeDevice.getDeviceId()); - break; - } - } - } - - public ActiveDevice getActiveDevice(long deviceId) { - return activeDevices.get(deviceId); - } - - public void updateDevice(final long deviceId, String status, Date time) { - Device device = Context.getIdentityManager().getById(deviceId); - if (device == null) { - return; - } - - String oldStatus = device.getStatus(); - device.setStatus(status); - - if (!status.equals(oldStatus)) { - String eventType; - Map events = new HashMap<>(); - switch (status) { - case Device.STATUS_ONLINE: - eventType = Event.TYPE_DEVICE_ONLINE; - break; - case Device.STATUS_UNKNOWN: - eventType = Event.TYPE_DEVICE_UNKNOWN; - if (updateDeviceState) { - events.putAll(updateDeviceState(deviceId)); - } - break; - default: - eventType = Event.TYPE_DEVICE_OFFLINE; - if (updateDeviceState) { - events.putAll(updateDeviceState(deviceId)); - } - break; - } - events.put(new Event(eventType, deviceId), null); - Context.getNotificationManager().updateEvents(events); - } - - Timeout timeout = timeouts.remove(deviceId); - if (timeout != null) { - timeout.cancel(); - } - - if (time != null) { - device.setLastUpdate(time); - } - - if (status.equals(Device.STATUS_ONLINE)) { - timeouts.put(deviceId, timer.newTimeout(timeout1 -> { - if (!timeout1.isCancelled()) { - updateDevice(deviceId, Device.STATUS_UNKNOWN, null); - } - }, deviceTimeout, TimeUnit.MILLISECONDS)); - } - - try { - Context.getDeviceManager().updateDeviceStatus(device); - } catch (StorageException e) { - LOGGER.warn("Update device status error", e); - } - - updateDevice(device); - } - - public Map updateDeviceState(long deviceId) { - DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); - Map result = new HashMap<>(); - - Map event = Main.getInjector() - .getInstance(MotionEventHandler.class).updateMotionState(deviceState); - if (event != null) { - result.putAll(event); - } - - event = Main.getInjector().getInstance(OverspeedEventHandler.class) - .updateOverspeedState(deviceState, Context.getDeviceManager(). - lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, true, false)); - if (event != null) { - result.putAll(event); - } - - return result; - } - - public synchronized void sendKeepalive() { - for (Set userListeners : listeners.values()) { - for (UpdateListener listener : userListeners) { - listener.onKeepalive(); - } - } - } - - public synchronized void updateDevice(Device device) { - for (long userId : Context.getPermissionsManager().getDeviceUsers(device.getId())) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { - listener.onUpdateDevice(device); - } - } - } - } - - public synchronized void updatePosition(Position position) { - long deviceId = position.getDeviceId(); - - for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { - listener.onUpdatePosition(position); - } - } - } - } - - public synchronized void updateEvent(long userId, Event event) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { - listener.onUpdateEvent(event); - } - } - } - - public interface UpdateListener { - void onKeepalive(); - void onUpdateDevice(Device device); - void onUpdatePosition(Position position); - void onUpdateEvent(Event event); - } - - public synchronized void addListener(long userId, UpdateListener listener) { - if (!listeners.containsKey(userId)) { - listeners.put(userId, new HashSet<>()); - } - listeners.get(userId).add(listener); - } - - public synchronized void removeListener(long userId, UpdateListener listener) { - if (!listeners.containsKey(userId)) { - listeners.put(userId, new HashSet<>()); - } - listeners.get(userId).remove(listener); - } - -} diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index a14fd7022..3b500aba9 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -31,7 +31,7 @@ import org.traccar.Context; import org.traccar.config.Keys; import org.traccar.model.Command; import org.traccar.model.Device; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.DeviceAccumulators; import org.traccar.model.Group; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 36df7aaf3..c7dcf3f59 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -22,7 +22,7 @@ import java.util.Map; import io.netty.channel.ChannelHandler; import org.traccar.database.CalendarManager; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.database.GeofenceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Calendar; diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 23a39d070..e27faf9ce 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -23,7 +23,7 @@ import io.netty.channel.ChannelHandler; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.ReportUtils; diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 102003c3c..84d80e55f 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -25,7 +25,7 @@ import org.traccar.config.Keys; import org.traccar.database.DeviceManager; import org.traccar.database.GeofenceManager; import org.traccar.model.Device; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/model/DeviceState.java b/src/main/java/org/traccar/model/DeviceState.java deleted file mode 100644 index 75d6726ee..000000000 --- a/src/main/java/org/traccar/model/DeviceState.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.model; - -public class DeviceState { - - private Boolean motionState; - - public void setMotionState(boolean motionState) { - this.motionState = motionState; - } - - public Boolean getMotionState() { - return motionState; - } - - private Position motionPosition; - - public void setMotionPosition(Position motionPosition) { - this.motionPosition = motionPosition; - } - - public Position getMotionPosition() { - return motionPosition; - } - - private Boolean overspeedState; - - public void setOverspeedState(boolean overspeedState) { - this.overspeedState = overspeedState; - } - - public Boolean getOverspeedState() { - return overspeedState; - } - - private Position overspeedPosition; - - public void setOverspeedPosition(Position overspeedPosition) { - this.overspeedPosition = overspeedPosition; - } - - public Position getOverspeedPosition() { - return overspeedPosition; - } - - private long overspeedGeofenceId; - - public void setOverspeedGeofenceId(long overspeedGeofenceId) { - this.overspeedGeofenceId = overspeedGeofenceId; - } - - public long getOverspeedGeofenceId() { - return overspeedGeofenceId; - } - -} diff --git a/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java b/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java index 7e3478704..1f940f7e2 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/AisProtocolDecoder.java b/src/main/java/org/traccar/protocol/AisProtocolDecoder.java index 8970f3d4a..a434e6e33 100644 --- a/src/main/java/org/traccar/protocol/AisProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AisProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitBuffer; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java index 25ccf6856..981437191 100644 --- a/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AlematicsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java b/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java index c48f59c90..0f9c2b17a 100644 --- a/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AnytrekProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java b/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java index c95a0366a..97ed7de96 100644 --- a/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ApelProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java index 692a2058a..0cd8ca37e 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java b/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java index 47e329234..8e182b9fb 100644 --- a/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AppelloProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java b/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java index 3c43ddf2a..50ff10469 100644 --- a/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java index 85e9ecfde..07653623a 100644 --- a/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Ardi01ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java index 4982e02fc..4def9c979 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java index b570f5423..22c0344d6 100644 --- a/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java index 50af039d6..cbed64f76 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.ObdDecoder; diff --git a/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java index e957a6911..0f6b7a33f 100644 --- a/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java index b99869e6e..9d82c9ad5 100644 --- a/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java b/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java index e6f546b9f..366bf9e8b 100644 --- a/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java b/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java index 43798eb67..b81ba306d 100644 --- a/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/At2000ProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 9a5d537ef..4567582db 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java b/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java index d7916147b..4489cf27e 100644 --- a/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AuroProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java b/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java index dc6f3d280..92dae7285 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java index aa05ca2d7..dd6a0e33c 100644 --- a/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoFonProtocolDecoder.java @@ -21,7 +21,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java index 5052450b5..f52ac81c9 100644 --- a/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoGradeProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java index da7f6b5a6..c072e55d0 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java b/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java index 37836ad5f..0793975df 100644 --- a/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java index 9f6ded26a..8f036fc29 100644 --- a/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Avl301ProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java index 854107a20..a45c315b3 100644 --- a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.CellTower; import org.traccar.model.Network; diff --git a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java index 535827f3c..2c9459584 100644 --- a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java b/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java index 474ceabdc..64fc439c4 100644 --- a/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BlackKiteProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java b/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java index f35ac6fbe..db59c564d 100644 --- a/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java index 853fa8f81..8e92b69fb 100644 --- a/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BoxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java index e735c67a1..42a61ef85 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java b/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java index 59b1fdf21..57f9c69ae 100644 --- a/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java index ce3345826..3f5418549 100644 --- a/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CarTrackProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java index ec640ba71..54ae068fb 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java @@ -20,7 +20,7 @@ import java.util.regex.Pattern; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.Parser.CoordinateFormat; diff --git a/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java index 161666adc..f13a1d0eb 100644 --- a/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CarscopProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index 85ac29336..c2b740c4c 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java index bddf19b41..37f733ac1 100644 --- a/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CautelaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java index 09bd3572f..ecd09a2d8 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java b/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java index d934921f1..90f8e0caf 100644 --- a/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java b/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java index 9c4c7e11d..1b5eb55d4 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Checksum; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java b/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java index 471afa0d6..280871e1e 100644 --- a/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ContinentalProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java index a282131ce..924603291 100644 --- a/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CradlepointProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java b/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java index 98fe4b7b3..580741ec9 100644 --- a/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DingtekProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java b/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java index 3223988ab..1327e7a6c 100644 --- a/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DishaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index 815cce987..807850778 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java index 96b06557a..0fd83f503 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java b/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java index d509b3ec0..b43635a52 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java index 3ef960f12..124bbfefa 100644 --- a/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Dsf22ProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index 3c15d41eb..c5835bc7d 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java b/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java index 9b02c898e..9cf40b011 100644 --- a/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DwayProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java index 4fcc48944..805cf1197 100644 --- a/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EasyTrackProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index 592e5a56c..f6b5720da 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -21,7 +21,7 @@ import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.socket.DatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java index e65ddb0ef..3a6af60a1 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java index bfa7a116b..dd1c8017b 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BufferUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java index 792ed1098..2198938e2 100644 --- a/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnnfuProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java index 65d5e3859..750ff2bda 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java index 27fcf1394..dd15c4276 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java b/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java index 14b4376d5..4239022d0 100644 --- a/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import io.netty.channel.socket.DatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java b/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java index 9fde6f0a0..706c70825 100644 --- a/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ExtremTracProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 53f35c3cd..741f4b35a 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index 281a8a84f..6e6f9c700 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index bcfbdd7da..2dec44e64 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.CellTower; import org.traccar.model.Network; diff --git a/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java index 068c0a05c..0d8bd9373 100644 --- a/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexCommProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java index 759f2cd6f..9fcee1aeb 100644 --- a/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexibleReportProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java index 9dce22ede..a0dac1c41 100644 --- a/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlextrackProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java index 449f00022..6dd0b0e95 100644 --- a/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FoxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java b/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java index 1d2dd3133..27dda1a6d 100644 --- a/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FreedomProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java index aded35823..4e5200f37 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java b/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java index c2f3781d9..57027b080 100644 --- a/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FutureWayProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index 4c6d915d5..a2ba7b029 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java index 087861635..644caee81 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java index b787b7467..6448b6a5a 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java index ae0383e5c..789d87dad 100644 --- a/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl100ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java index c3339bea5..ecd1f5bfa 100644 --- a/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitBuffer; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 72d3ef592..ebd58ed5c 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -16,7 +16,7 @@ package org.traccar.protocol; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java index d5c834284..720b61695 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java index b742d0cac..e537edf1d 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java @@ -27,7 +27,7 @@ import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java b/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java index c9c221a69..9c8b6879a 100644 --- a/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GnxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java index a86249224..77649a041 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java index 0f8d29228..5c8d0bac2 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java index 0ba79bb51..eea64364e 100644 --- a/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps056ProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index 510f5eca2..a2009e1b2 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java b/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java index c158d3212..82da58f1e 100644 --- a/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GpsGateProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java b/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java index bbb2c31e2..0fef4b7da 100644 --- a/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GpsMarkerProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java b/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java index 31f9401b4..a9b85d255 100644 --- a/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GpsmtaProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java b/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java index 292e43a0e..dfc3c10f6 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GranitProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java index 2496aad48..352070107 100644 --- a/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gs100ProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java index 78a3fd3ee..4ecb0b43b 100644 --- a/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt02ProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 22f38a497..c200c6ba9 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java index abf208a46..fb3a2b8ae 100644 --- a/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java index dcfb36fd1..2ad4f644b 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java b/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java index dd20f2aeb..9903e7735 100644 --- a/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HaicomProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java b/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java index a93572b5c..5541cb065 100644 --- a/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HomtecsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java index af51a99c6..708c74f2a 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 891046213..371691d82 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 84120028a..c75fd673a 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java b/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java index 06bc12d59..eada1fd9a 100644 --- a/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HunterProProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java b/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java index cf3c03d7f..72409b168 100644 --- a/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IdplProtocolDecoder.java @@ -20,7 +20,7 @@ import java.util.regex.Pattern; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.Parser.CoordinateFormat; diff --git a/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java b/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java index 930d4f23b..b86584016 100644 --- a/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java index 9c94ffd4b..57e4c736f 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java @@ -25,7 +25,7 @@ import io.netty.handler.codec.mqtt.MqttMessageBuilders; import io.netty.handler.codec.mqtt.MqttPublishMessage; import io.netty.handler.codec.mqtt.MqttSubscribeMessage; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java index 9eed58347..1ed9a7d8c 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java index 63556e7a9..972f22ebe 100644 --- a/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java b/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java index 40fa8864d..98fb36e11 100644 --- a/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java b/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java index 33026918a..ffddcc568 100644 --- a/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/JpKorjarProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index 2c1b5dcec..9fa550ded 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java b/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java index 63812242a..fb989c72e 100644 --- a/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/KenjiProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java b/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java index a14f9b8a4..d7c236c4f 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java b/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java index 5b5eb7d60..820de8f1c 100644 --- a/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java b/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java index 132087c8f..809fafc90 100644 --- a/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LacakProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateUtil; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index d8554dc13..c55c0624d 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java index ad0c9bd32..6affb85c5 100644 --- a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java @@ -22,7 +22,7 @@ import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java b/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java index 1460bb176..9415d0f07 100644 --- a/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/M2cProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java b/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java index 21e4a2fd0..7eca93a59 100644 --- a/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/M2mProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java b/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java index 37b097414..78308658e 100644 --- a/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MaestroProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java index 2c7b7eb40..8ac13b4d4 100644 --- a/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ManPowerProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java index 431258388..fac930ba8 100644 --- a/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Mavlink2ProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java b/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java index 7233280c2..06b6f0e76 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index 528098363..0b6bf8663 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 3ab449350..30689436d 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java index c72a742b9..84ba75e7c 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java b/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java index 901ceb8f7..21c629411 100644 --- a/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MilesmateProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java index d5be31cec..f2e5eb905 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index c63226c80..228578571 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index 86c89e336..d7600ecbb 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java b/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java index 3116d073c..8e6679b05 100644 --- a/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MoovboxProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; import org.w3c.dom.Document; diff --git a/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java b/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java index 8ce4fe8b1..9bca4d9bc 100644 --- a/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MotorProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java index 88419b871..896c7a2d2 100644 --- a/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java @@ -26,7 +26,7 @@ import io.netty.handler.codec.http.HttpVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java b/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java index d1207bedf..e94d12b36 100644 --- a/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MtxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java index 379b610e1..b3e2295e8 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MxtProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java index db5521201..6dadbc559 100644 --- a/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java index 7ba474ae0..53631bd4e 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java index 10d71d76c..47d10b310 100644 --- a/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 5fb3e771f..9122eb362 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java b/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java index 6b5596dba..18ebc49da 100644 --- a/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NeosProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/NetProtocolDecoder.java b/src/main/java/org/traccar/protocol/NetProtocolDecoder.java index c71a792a2..ebffb06f1 100644 --- a/src/main/java/org/traccar/protocol/NetProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NetProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java index 47c6e2ffd..16d992938 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java b/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java index 53dae7fd6..53b58f9b6 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java b/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java index 5d1159f7d..f826c4121 100644 --- a/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NvsProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java b/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java index 62b41a2ea..49bc5b824 100644 --- a/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java b/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java index 1c9771ce9..bf0ba6f82 100644 --- a/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ObdDongleProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java index b9cc71e8c..b0c7c3bc6 100644 --- a/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OigoProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java b/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java index fa35ab455..3bb62acb9 100644 --- a/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java index f90d1f2b3..9d747032b 100644 --- a/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java @@ -21,7 +21,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java index b76cbfa85..255a81ae6 100644 --- a/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OpenGtsProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index 7277b1e5f..8ec47908f 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpResponse; import org.traccar.BasePipelineFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java index af819989e..681891edb 100644 --- a/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrionProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java index ec9bbc240..178ec344f 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -22,7 +22,7 @@ import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.database.CommandsManager; import org.traccar.helper.DateUtil; diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java index 9de77d241..62b873be7 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java b/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java index 509d14ae4..71ac87168 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java index b5d34a029..7079745be 100644 --- a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java b/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java index 02a15e34a..3e7fa9a5b 100644 --- a/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PathAwayProtocolDecoder.java @@ -24,7 +24,7 @@ import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 26ce2fe53..244df6806 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -22,7 +22,7 @@ import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java index 65de211ac..6ee95d18a 100644 --- a/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java b/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java index ce45abef6..028de5424 100644 --- a/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PolteProtocolDecoder.java @@ -19,7 +19,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java b/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java index e1847a2b2..da9403313 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java index a19384e62..ff6ad763a 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java b/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java index 190c68258..5f6805f09 100644 --- a/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PricolProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java b/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java index 0025cd9e7..e3a5881da 100644 --- a/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ProgressProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/PstProtocolDecoder.java b/src/main/java/org/traccar/protocol/PstProtocolDecoder.java index e3fe1af62..872e77a3a 100644 --- a/src/main/java/org/traccar/protocol/PstProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PstProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java index 48ce7dede..f669c5ffd 100644 --- a/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java index e7f9e062a..c33660f51 100644 --- a/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt3000ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java index 0817d527d..21b91203f 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java index 6a3fe2734..94b549fe6 100644 --- a/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt60ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java b/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java index d60318447..3be784911 100644 --- a/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/R12wProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java index f441bf8ed..89639ad30 100644 --- a/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java b/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java index d87f77b84..818e97f8b 100644 --- a/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RadarProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java b/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java index 50acd20a1..dfc21bf69 100644 --- a/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RaveonProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java index 04098225f..0c417a62f 100644 --- a/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RecodaProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java index 5bf6cef50..afbf7e511 100644 --- a/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java b/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java index 46267ca90..501d5faa7 100644 --- a/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RitiProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java index b613f31d7..ffe16bd7b 100644 --- a/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RoboTrackProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/RstProtocolDecoder.java b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java index 9e3261a04..fcc96fbf1 100644 --- a/src/main/java/org/traccar/protocol/RstProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 7abb52bd0..77df0deb7 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java index 6d565517b..a88bfa65a 100644 --- a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; diff --git a/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java b/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java index 3033aa2cc..71279812c 100644 --- a/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SabertekProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java b/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java index 7e1c158e6..6741cb67c 100644 --- a/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SanavProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java b/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java index 036d1ee51..9568cd6d3 100644 --- a/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SanulProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java b/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java index c457d5620..37a84be04 100644 --- a/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SatsolProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java index ce577f392..bbb8bc1cc 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -22,7 +22,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java b/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java index bf8bfab77..7ba501834 100644 --- a/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SiwiProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java b/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java index 818acd805..6ffcbbe44 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java b/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java index 04920c969..7fc38f061 100644 --- a/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SmartSoleProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java b/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java index 9da52e97a..2244ad289 100644 --- a/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SmokeyProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java b/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java index 9d5dc072f..0432fbd03 100644 --- a/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java b/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java index 34417d95f..d493b748d 100644 --- a/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SpotProtocolDecoder.java @@ -20,7 +20,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateUtil; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index afccb3a6b..0ff668fa8 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java index 5ffddb318..56ab733c8 100644 --- a/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index 8a7b5cec7..53c02f28c 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java index cc985d605..c07337fc5 100644 --- a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java @@ -20,7 +20,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java index 7b0055aa1..dc1fa3ba3 100644 --- a/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Stl060ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index fca7661f7..6340def86 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java b/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java index 40a25bb91..f53f0f598 100644 --- a/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SupermateProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java b/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java index 7e783f6cd..d7b126167 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SviasProtocolDecoder.java @@ -24,7 +24,7 @@ import org.traccar.helper.PatternBuilder; import java.net.SocketAddress; import java.util.regex.Pattern; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.helper.Parser; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java index 8d0b31c8f..b1cff8b64 100644 --- a/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SwiftechProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index acfab5598..3d892c021 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java index 2a3cca3e4..d9fd1c8cf 100644 --- a/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T57ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index d554c2999..b7a89f2e9 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java index ec0ce1931..e5e84b7c4 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java index b6091136a..94efacc63 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java index 6b9f0edb6..09efcb7d4 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TekProtocolDecoder.java b/src/main/java/org/traccar/protocol/TekProtocolDecoder.java index 33ff51d2d..819c7e819 100644 --- a/src/main/java/org/traccar/protocol/TekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TekProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java b/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java index 9369ab101..f6f6f5379 100644 --- a/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TelemaxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java index a4f9e2989..9681dc565 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 03a5a00ea..f91eef837 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java index c36da2aed..313210f63 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java index b3f943078..085ce4c91 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Checksum; diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java index 82033598d..796b726ea 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java index da0c6928b..af29fbc21 100644 --- a/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk102ProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java index 476d1d682..e197a8a41 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java index ad7dfa886..3d219fc09 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java index 36cf7859f..7870c778a 100644 --- a/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java b/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java index d27849f8c..00dc2a09b 100644 --- a/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java index 6de053c32..92a7b5c9d 100644 --- a/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopflytechProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java index 4fe261aa4..a1d5481db 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index b76d5b307..4f520f360 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java index 2f11bd152..0306770b6 100644 --- a/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java index 319194c21..da0e8d292 100644 --- a/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tr900ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java index db8022738..10483d445 100644 --- a/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrackboxProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java index 4d5cb18f5..b1f50dc10 100644 --- a/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java index e42e2f670..21dd78da3 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateUtil; diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java index e62cdf404..9df29ae1b 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java index 1010528c4..cbc983000 100644 --- a/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tt8850ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java b/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java index 93d3a63d2..6169e0545 100644 --- a/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index b1ddc5203..8e84a6781 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java index 7fec0bf8b..e6cc0a891 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java index 9f236a7e5..bdc6bf24e 100644 --- a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java b/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java index 1081fa811..b9065e7f3 100644 --- a/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UuxProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java b/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java index 40267022b..237aea39b 100644 --- a/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/V680ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java b/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java index c4787bda2..9ab871bfe 100644 --- a/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VisiontekProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java b/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java index 1ee00bd3f..048c89e1e 100644 --- a/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VnetProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; diff --git a/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java index 84ad09caa..a8fc801e7 100644 --- a/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BcdUtil; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java b/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java index 17fac4311..bf0cdcb51 100644 --- a/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 3967fb804..35fdc3ca5 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 19d9dd6c8..8dd7aab24 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java index 976d4fb27..ec1c4d17a 100644 --- a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; diff --git a/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java b/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java index b85ae2656..22d7bade3 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java b/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java index 58b5784d0..323992ddd 100644 --- a/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java @@ -19,7 +19,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 766a3f05b..501897715 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -20,7 +20,7 @@ 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.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; diff --git a/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java b/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java index 73d386477..e41d467d5 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java index b53a42ac3..220c28054 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import io.netty.channel.socket.nio.NioDatagramChannel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.config.Keys; diff --git a/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java index 69e5b7372..88f2d07e5 100644 --- a/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; diff --git a/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java index f49fb9563..ab0b2cdaa 100644 --- a/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xt013ProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; diff --git a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java index b3f6493a8..edcb3f535 100644 --- a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -18,7 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.config.Keys; import org.traccar.helper.DataConverter; diff --git a/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java b/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java index bf5a23fa7..fd050bee9 100644 --- a/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/YwtProtocolDecoder.java @@ -17,7 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.DeviceSession; +import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.Parser; diff --git a/src/main/java/org/traccar/reports/ReportUtils.java b/src/main/java/org/traccar/reports/ReportUtils.java index dd1ef478f..413d49ad7 100644 --- a/src/main/java/org/traccar/reports/ReportUtils.java +++ b/src/main/java/org/traccar/reports/ReportUtils.java @@ -31,7 +31,7 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.Driver; import org.traccar.model.Event; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/session/ActiveDevice.java b/src/main/java/org/traccar/session/ActiveDevice.java new file mode 100644 index 000000000..af19ba55b --- /dev/null +++ b/src/main/java/org/traccar/session/ActiveDevice.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015 - 2020 Anton Tananaev (anton@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.session; + +import io.netty.channel.Channel; +import io.netty.handler.codec.http.HttpRequestDecoder; +import org.traccar.BasePipelineFactory; +import org.traccar.Protocol; +import org.traccar.model.Command; + +import java.net.SocketAddress; + +public class ActiveDevice { + + private final long deviceId; + private final Protocol protocol; + private final Channel channel; + private final SocketAddress remoteAddress; + private final boolean supportsLiveCommands; + + public ActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { + this.deviceId = deviceId; + this.protocol = protocol; + this.channel = channel; + this.remoteAddress = remoteAddress; + supportsLiveCommands = BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) == null; + } + + public Channel getChannel() { + return channel; + } + + public long getDeviceId() { + return deviceId; + } + + public boolean supportsLiveCommands() { + return supportsLiveCommands; + } + + public void sendCommand(Command command) { + protocol.sendDataCommand(channel, remoteAddress, command); + } + +} diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java new file mode 100644 index 000000000..fbc15b00d --- /dev/null +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -0,0 +1,218 @@ +/* + * Copyright 2015 - 2022 Anton Tananaev (anton@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.session; + +import io.netty.channel.Channel; +import io.netty.util.Timeout; +import io.netty.util.Timer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.Context; +import org.traccar.Main; +import org.traccar.Protocol; +import org.traccar.config.Keys; +import org.traccar.handler.events.MotionEventHandler; +import org.traccar.handler.events.OverspeedEventHandler; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.storage.StorageException; + +import java.net.SocketAddress; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +public class ConnectionManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); + + private final long deviceTimeout; + private final boolean updateDeviceState; + + private final Map activeDevices = new ConcurrentHashMap<>(); + private final Map> listeners = new ConcurrentHashMap<>(); + private final Map timeouts = new ConcurrentHashMap<>(); + + private final Timer timer; + + public ConnectionManager() { + deviceTimeout = Context.getConfig().getLong(Keys.STATUS_TIMEOUT) * 1000; + updateDeviceState = Context.getConfig().getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); + timer = Main.getInjector().getInstance(Timer.class); + } + + public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { + activeDevices.put(deviceId, new ActiveDevice(deviceId, protocol, channel, remoteAddress)); + } + + public void removeActiveDevice(Channel channel) { + for (ActiveDevice activeDevice : activeDevices.values()) { + if (activeDevice.getChannel() == channel) { + updateDevice(activeDevice.getDeviceId(), Device.STATUS_OFFLINE, null); + activeDevices.remove(activeDevice.getDeviceId()); + break; + } + } + } + + public ActiveDevice getActiveDevice(long deviceId) { + return activeDevices.get(deviceId); + } + + public void updateDevice(final long deviceId, String status, Date time) { + Device device = Context.getIdentityManager().getById(deviceId); + if (device == null) { + return; + } + + String oldStatus = device.getStatus(); + device.setStatus(status); + + if (!status.equals(oldStatus)) { + String eventType; + Map events = new HashMap<>(); + switch (status) { + case Device.STATUS_ONLINE: + eventType = Event.TYPE_DEVICE_ONLINE; + break; + case Device.STATUS_UNKNOWN: + eventType = Event.TYPE_DEVICE_UNKNOWN; + if (updateDeviceState) { + events.putAll(updateDeviceState(deviceId)); + } + break; + default: + eventType = Event.TYPE_DEVICE_OFFLINE; + if (updateDeviceState) { + events.putAll(updateDeviceState(deviceId)); + } + break; + } + events.put(new Event(eventType, deviceId), null); + Context.getNotificationManager().updateEvents(events); + } + + Timeout timeout = timeouts.remove(deviceId); + if (timeout != null) { + timeout.cancel(); + } + + if (time != null) { + device.setLastUpdate(time); + } + + if (status.equals(Device.STATUS_ONLINE)) { + timeouts.put(deviceId, timer.newTimeout(timeout1 -> { + if (!timeout1.isCancelled()) { + updateDevice(deviceId, Device.STATUS_UNKNOWN, null); + } + }, deviceTimeout, TimeUnit.MILLISECONDS)); + } + + try { + Context.getDeviceManager().updateDeviceStatus(device); + } catch (StorageException e) { + LOGGER.warn("Update device status error", e); + } + + updateDevice(device); + } + + public Map updateDeviceState(long deviceId) { + DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); + Map result = new HashMap<>(); + + Map event = Main.getInjector() + .getInstance(MotionEventHandler.class).updateMotionState(deviceState); + if (event != null) { + result.putAll(event); + } + + event = Main.getInjector().getInstance(OverspeedEventHandler.class) + .updateOverspeedState(deviceState, Context.getDeviceManager(). + lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, true, false)); + if (event != null) { + result.putAll(event); + } + + return result; + } + + public synchronized void sendKeepalive() { + for (Set userListeners : listeners.values()) { + for (UpdateListener listener : userListeners) { + listener.onKeepalive(); + } + } + } + + public synchronized void updateDevice(Device device) { + for (long userId : Context.getPermissionsManager().getDeviceUsers(device.getId())) { + if (listeners.containsKey(userId)) { + for (UpdateListener listener : listeners.get(userId)) { + listener.onUpdateDevice(device); + } + } + } + } + + public synchronized void updatePosition(Position position) { + long deviceId = position.getDeviceId(); + + for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) { + if (listeners.containsKey(userId)) { + for (UpdateListener listener : listeners.get(userId)) { + listener.onUpdatePosition(position); + } + } + } + } + + public synchronized void updateEvent(long userId, Event event) { + if (listeners.containsKey(userId)) { + for (UpdateListener listener : listeners.get(userId)) { + listener.onUpdateEvent(event); + } + } + } + + public interface UpdateListener { + void onKeepalive(); + void onUpdateDevice(Device device); + void onUpdatePosition(Position position); + void onUpdateEvent(Event event); + } + + public synchronized void addListener(long userId, UpdateListener listener) { + if (!listeners.containsKey(userId)) { + listeners.put(userId, new HashSet<>()); + } + listeners.get(userId).add(listener); + } + + public synchronized void removeListener(long userId, UpdateListener listener) { + if (!listeners.containsKey(userId)) { + listeners.put(userId, new HashSet<>()); + } + listeners.get(userId).remove(listener); + } + +} diff --git a/src/main/java/org/traccar/session/DeviceSession.java b/src/main/java/org/traccar/session/DeviceSession.java new file mode 100644 index 000000000..6fe5b5d57 --- /dev/null +++ b/src/main/java/org/traccar/session/DeviceSession.java @@ -0,0 +1,42 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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.session; + +import java.util.TimeZone; + +public class DeviceSession { + + private final long deviceId; + + public DeviceSession(long deviceId) { + this.deviceId = deviceId; + } + + public long getDeviceId() { + return deviceId; + } + + private TimeZone timeZone; + + public void setTimeZone(TimeZone timeZone) { + this.timeZone = timeZone; + } + + public TimeZone getTimeZone() { + return timeZone; + } + +} diff --git a/src/main/java/org/traccar/session/DeviceState.java b/src/main/java/org/traccar/session/DeviceState.java new file mode 100644 index 000000000..b7248688a --- /dev/null +++ b/src/main/java/org/traccar/session/DeviceState.java @@ -0,0 +1,73 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@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.session; + +import org.traccar.model.Position; + +public class DeviceState { + + private Boolean motionState; + + public void setMotionState(boolean motionState) { + this.motionState = motionState; + } + + public Boolean getMotionState() { + return motionState; + } + + private Position motionPosition; + + public void setMotionPosition(Position motionPosition) { + this.motionPosition = motionPosition; + } + + public Position getMotionPosition() { + return motionPosition; + } + + private Boolean overspeedState; + + public void setOverspeedState(boolean overspeedState) { + this.overspeedState = overspeedState; + } + + public Boolean getOverspeedState() { + return overspeedState; + } + + private Position overspeedPosition; + + public void setOverspeedPosition(Position overspeedPosition) { + this.overspeedPosition = overspeedPosition; + } + + public Position getOverspeedPosition() { + return overspeedPosition; + } + + private long overspeedGeofenceId; + + public void setOverspeedGeofenceId(long overspeedGeofenceId) { + this.overspeedGeofenceId = overspeedGeofenceId; + } + + public long getOverspeedGeofenceId() { + return overspeedGeofenceId; + } + +} diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 0f6c55857..a33bb2b5d 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,7 +1,7 @@ package org.traccar; import org.traccar.config.Config; -import org.traccar.database.ConnectionManager; +import org.traccar.session.ConnectionManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index f57c16635..8d84e3125 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -15,7 +15,7 @@ import java.util.TimeZone; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.model.TripsConfig; diff --git a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java index 515f37b5d..5c4cce1b6 100644 --- a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.traccar.BaseTest; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.model.DeviceState; +import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; -- cgit v1.2.3 From 2e83b23d258e74df6dfc1c860c2abf9b1b816181 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 16:45:55 -0700 Subject: Remove unused code --- .../java/org/traccar/database/DeviceManager.java | 45 +--------------------- 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 3b500aba9..0e5056e57 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 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,6 @@ public class DeviceManager extends BaseObjectManager implements Identity private final long dataRefreshDelay; private Map devicesByUniqueId; - private Map devicesByPhone; private final AtomicLong devicesLastUpdate = new AtomicLong(); private final Map positions = new ConcurrentHashMap<>(); @@ -58,9 +57,6 @@ public class DeviceManager extends BaseObjectManager implements Identity this.config = Context.getConfig(); try { writeLock(); - if (devicesByPhone == null) { - devicesByPhone = new ConcurrentHashMap<>(); - } if (devicesByUniqueId == null) { devicesByUniqueId = new ConcurrentHashMap<>(); } @@ -216,39 +212,10 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - private void addByPhone(Device device) { - try { - writeLock(); - if (devicesByPhone == null) { - devicesByPhone = new ConcurrentHashMap<>(); - } - devicesByPhone.put(device.getPhone(), device); - } finally { - writeUnlock(); - } - } - - private void removeByPhone(String phone) { - if (phone == null || phone.isEmpty()) { - return; - } - try { - writeLock(); - if (devicesByPhone != null) { - devicesByPhone.remove(phone); - } - } finally { - writeUnlock(); - } - } - @Override protected void addNewItem(Device device) { super.addNewItem(device); addByUniqueId(device); - if (device.getPhone() != null && !device.getPhone().isEmpty()) { - addByPhone(device); - } if (Context.getGeofenceManager() != null) { Position lastPosition = getLastPosition(device.getId()); if (lastPosition != null) { @@ -264,6 +231,7 @@ public class DeviceManager extends BaseObjectManager implements Identity cachedDevice.setGroupId(device.getGroupId()); cachedDevice.setCategory(device.getCategory()); cachedDevice.setContact(device.getContact()); + cachedDevice.setPhone(device.getPhone()); cachedDevice.setModel(device.getModel()); cachedDevice.setDisabled(device.getDisabled()); cachedDevice.setAttributes(device.getAttributes()); @@ -272,13 +240,6 @@ public class DeviceManager extends BaseObjectManager implements Identity cachedDevice.setUniqueId(device.getUniqueId()); addByUniqueId(cachedDevice); } - if (device.getPhone() != null && !device.getPhone().isEmpty() - && !device.getPhone().equals(cachedDevice.getPhone())) { - String phone = cachedDevice.getPhone(); - removeByPhone(phone); - cachedDevice.setPhone(device.getPhone()); - addByPhone(cachedDevice); - } } @Override @@ -286,10 +247,8 @@ public class DeviceManager extends BaseObjectManager implements Identity Device cachedDevice = getById(deviceId); if (cachedDevice != null) { String deviceUniqueId = cachedDevice.getUniqueId(); - String phone = cachedDevice.getPhone(); super.removeCachedItem(deviceId); removeByUniqueId(deviceUniqueId); - removeByPhone(phone); } positions.remove(deviceId); } -- cgit v1.2.3 From 9a68d1045f30bf8397d6cbf90df8f42f40979591 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 16:58:34 -0700 Subject: Add generic variable store --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 28 +++++++++++----------- .../traccar/protocol/HuabaoProtocolDecoder.java | 8 +++---- .../traccar/protocol/UlbotechProtocolDecoder.java | 8 ++++--- .../java/org/traccar/session/DeviceSession.java | 24 ++++++++++++++----- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index c200c6ba9..0f89597ce 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -444,8 +444,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } position.setDeviceId(deviceSession.getDeviceId()); - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } } @@ -455,8 +455,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // type deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession != null && deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (deviceSession != null && !deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } if (dataLength > 10) { @@ -468,7 +468,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { offset = -offset; } if (deviceSession != null) { - TimeZone timeZone = deviceSession.getTimeZone(); + TimeZone timeZone = deviceSession.get(DeviceSession.KEY_TIMEZONE); if (timeZone.getRawOffset() == 0) { timeZone.setRawOffset(offset * 1000); deviceSession.setTimeZone(timeZone); @@ -531,7 +531,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedInt(); // data and alarm - decodeGps(position, buf, false, deviceSession.getTimeZone()); + decodeGps(position, buf, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); buf.readUnsignedShort(); // terminal info @@ -653,7 +653,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5; - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); @@ -769,7 +769,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasGps(type)) { - decodeGps(position, buf, false, deviceSession.getTimeZone()); + decodeGps(position, buf, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); } else { getLastLocation(position, null); } @@ -858,9 +858,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { boolean extendedAlarm = dataLength > 7; if (extendedAlarm) { - decodeGps(position, buf, false, false, false, deviceSession.getTimeZone()); + decodeGps(position, buf, false, false, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); } else { - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); getLastLocation(position, dateBuilder.getDate()); @@ -925,8 +925,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } Position position = new Position(getProtocolName()); @@ -1033,7 +1033,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_AZ735_GPS || type == MSG_AZ735_ALARM) { - if (!decodeGps(position, buf, true, deviceSession.getTimeZone())) { + if (!decodeGps(position, buf, true, deviceSession.get(DeviceSession.KEY_TIMEZONE))) { getLastLocation(position, position.getDeviceTime()); } @@ -1078,7 +1078,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_OBD) { - DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone()) + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index c75fd673a..00093c978 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -198,8 +198,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return null; } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId(), "GMT+8")); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId(), "GMT+8")); } if (type == MSG_TERMINAL_REGISTER) { @@ -407,7 +407,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.setAltitude(buf.readShort()); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort()); - position.setTime(readDate(buf, deviceSession.getTimeZone())); + position.setTime(readDate(buf, deviceSession.get(DeviceSession.KEY_TIMEZONE))); if (buf.readableBytes() == 20) { @@ -642,7 +642,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - Date time = readDate(buf, deviceSession.getTimeZone()); + Date time = readDate(buf, deviceSession.get(DeviceSession.KEY_TIMEZONE)); if (buf.readUnsignedByte() > 0) { position.set(Position.KEY_ARCHIVE, true); diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java index e6cc0a891..c9b35158e 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -37,6 +37,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.TimeZone; import java.util.regex.Pattern; public class UlbotechProtocolDecoder extends BaseProtocolDecoder { @@ -214,16 +215,17 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { return null; } - if (deviceSession.getTimeZone() == null) { - deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId())); + if (!deviceSession.contains(DeviceSession.KEY_TIMEZONE)) { + deviceSession.set(DeviceSession.KEY_TIMEZONE, getTimeZone(deviceSession.getDeviceId())); } Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + TimeZone timeZone = deviceSession.get(DeviceSession.KEY_TIMEZONE); long seconds = buf.readUnsignedInt() & 0x7fffffffL; seconds += 946684800L; // 2000-01-01 00:00 - seconds -= deviceSession.getTimeZone().getRawOffset() / 1000; + seconds -= timeZone.getRawOffset() / 1000; Date time = new Date(seconds * 1000); boolean hasLocation = false; diff --git a/src/main/java/org/traccar/session/DeviceSession.java b/src/main/java/org/traccar/session/DeviceSession.java index 6fe5b5d57..0d5b283fe 100644 --- a/src/main/java/org/traccar/session/DeviceSession.java +++ b/src/main/java/org/traccar/session/DeviceSession.java @@ -15,7 +15,8 @@ */ package org.traccar.session; -import java.util.TimeZone; +import java.util.HashMap; +import java.util.Map; public class DeviceSession { @@ -29,14 +30,25 @@ public class DeviceSession { return deviceId; } - private TimeZone timeZone; + public static final String KEY_TIMEZONE = "timezone"; - public void setTimeZone(TimeZone timeZone) { - this.timeZone = timeZone; + private final Map locals = new HashMap<>(); + + public boolean contains(String key) { + return locals.containsKey(key); + } + + public void set(String key, Object value) { + if (value != null) { + locals.put(key, value); + } else { + locals.remove(key); + } } - public TimeZone getTimeZone() { - return timeZone; + @SuppressWarnings("unchecked") + public T get(String key) { + return (T) locals.get(key); } } -- cgit v1.2.3 From 4dc602d8a7700924b0117424533046b28f4a8df4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 18:39:50 -0700 Subject: Combine active device and session --- src/main/java/org/traccar/BaseProtocolDecoder.java | 99 +--------------------- src/main/java/org/traccar/MainEventHandler.java | 2 +- src/main/java/org/traccar/config/Keys.java | 14 --- .../java/org/traccar/database/CommandsManager.java | 12 +-- .../java/org/traccar/database/DeviceManager.java | 6 +- .../java/org/traccar/database/IdentityManager.java | 2 +- .../org/traccar/protocol/EgtsProtocolDecoder.java | 2 +- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- .../traccar/protocol/OrbcommProtocolDecoder.java | 3 +- .../java/org/traccar/session/ActiveDevice.java | 58 ------------- .../org/traccar/session/ConnectionManager.java | 81 +++++++++++++++--- .../java/org/traccar/session/DeviceSession.java | 40 ++++++++- src/main/java/org/traccar/session/Endpoint.java | 58 +++++++++++++ src/test/java/org/traccar/BaseTest.java | 27 +++++- 14 files changed, 208 insertions(+), 198 deletions(-) delete mode 100644 src/main/java/org/traccar/session/ActiveDevice.java create mode 100644 src/main/java/org/traccar/session/Endpoint.java diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 3fc6e7697..d6c571b79 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -18,14 +18,9 @@ package org.traccar; import com.google.inject.Inject; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; -import io.netty.channel.socket.DatagramChannel; -import io.netty.handler.codec.http.HttpRequestDecoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.CommandsManager; -import org.traccar.session.ConnectionManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; @@ -33,22 +28,19 @@ import org.traccar.helper.UnitsConverter; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Collection; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.TimeZone; public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { - private static final Logger LOGGER = LoggerFactory.getLogger(BaseProtocolDecoder.class); - private static final String PROTOCOL_UNKNOWN = "unknown"; private final Protocol protocol; @@ -147,95 +139,8 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { return result; } - private DeviceSession channelDeviceSession; // connection-based protocols - private final Map addressDeviceSessions = new HashMap<>(); // connectionless protocols - - private long findDeviceId(SocketAddress remoteAddress, String... uniqueIds) { - if (uniqueIds.length > 0) { - long deviceId = 0; - Device device = null; - try { - for (String uniqueId : uniqueIds) { - if (uniqueId != null) { - device = identityManager.getByUniqueId(uniqueId); - if (device != null) { - deviceId = device.getId(); - break; - } - } - } - } catch (Exception e) { - LOGGER.warn("Find device error", e); - } - if (deviceId == 0 && config.getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { - return identityManager.addUnknownDevice(uniqueIds[0]); - } - if (device != null && !device.getDisabled()) { - return deviceId; - } - StringBuilder message = new StringBuilder(); - if (deviceId == 0) { - message.append("Unknown device -"); - } else { - message.append("Disabled device -"); - } - for (String uniqueId : uniqueIds) { - message.append(" ").append(uniqueId); - } - if (remoteAddress != null) { - message.append(" (").append(((InetSocketAddress) remoteAddress).getHostString()).append(")"); - } - LOGGER.warn(message.toString()); - } - return 0; - } - 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(Keys.PROTOCOL_IGNORE_SESSIONS_CACHE.withPrefix(getProtocolName())) - || config.getBoolean(Keys.DECODER_IGNORE_SESSIONS_CACHE)) { - long deviceId = findDeviceId(remoteAddress, uniqueIds); - if (deviceId != 0) { - if (connectionManager != null) { - connectionManager.addActiveDevice(deviceId, protocol, channel, remoteAddress); - } - return new DeviceSession(deviceId); - } else { - return null; - } - } - if (channel instanceof DatagramChannel) { - long deviceId = findDeviceId(remoteAddress, uniqueIds); - DeviceSession deviceSession = addressDeviceSessions.get(remoteAddress); - if (deviceSession != null && (deviceSession.getDeviceId() == deviceId || uniqueIds.length == 0)) { - return deviceSession; - } else if (deviceId != 0) { - deviceSession = new DeviceSession(deviceId); - addressDeviceSessions.put(remoteAddress, deviceSession); - if (connectionManager != null) { - connectionManager.addActiveDevice(deviceId, protocol, channel, remoteAddress); - } - return deviceSession; - } else { - return null; - } - } else { - if (channelDeviceSession == null) { - long deviceId = findDeviceId(remoteAddress, uniqueIds); - if (deviceId != 0) { - channelDeviceSession = new DeviceSession(deviceId); - if (connectionManager != null) { - connectionManager.addActiveDevice(deviceId, protocol, channel, remoteAddress); - } - } - } - return channelDeviceSession; - } + return connectionManager.getDeviceSession(protocol, channel, remoteAddress, uniqueIds); } public void getLastLocation(Position position, Date deviceTime) { diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 91706222a..0a25b7547 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -130,7 +130,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName())) { - Context.getConnectionManager().removeActiveDevice(ctx.channel()); + Context.getConnectionManager().removeDeviceSessions(ctx.channel()); } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index eebdf7172..f5370874d 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -190,13 +190,6 @@ public final class Keys { ".server", Collections.singletonList(KeyType.GLOBAL)); - /** - * Skip device connection session cache. Per protocol configuration. - */ - public static final ConfigSuffix PROTOCOL_IGNORE_SESSIONS_CACHE = new ConfigSuffix<>( - ".ignoreSessionCache", - Collections.singletonList(KeyType.GLOBAL)); - /** * ORBCOMM API access id. */ @@ -211,13 +204,6 @@ public final class Keys { "orbcomm.password", Collections.singletonList(KeyType.GLOBAL)); - /** - * Skip device connection session cache. Global configuration. - */ - public static final ConfigKey DECODER_IGNORE_SESSIONS_CACHE = new ConfigKey<>( - "decoder.ignoreSessionCache", - Collections.singletonList(KeyType.GLOBAL)); - /** * Server wide connection timeout value in seconds. See protocol timeout for more information. */ diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 3adf5d2e9..57ce0f9a4 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -34,7 +34,7 @@ import org.traccar.Context; import org.traccar.model.Command; import org.traccar.model.Typed; import org.traccar.model.Position; -import org.traccar.session.ActiveDevice; +import org.traccar.session.DeviceSession; public class CommandsManager extends ExtendedObjectManager { @@ -75,10 +75,10 @@ public class CommandsManager extends ExtendedObjectManager { throw new RuntimeException("Command " + command.getType() + " is not supported"); } } else { - ActiveDevice activeDevice = Context.getConnectionManager().getActiveDevice(deviceId); - if (activeDevice != null) { - if (activeDevice.supportsLiveCommands()) { - activeDevice.sendCommand(command); + DeviceSession deviceSession = Context.getConnectionManager().getDeviceSession(deviceId); + if (deviceSession != null) { + if (deviceSession.supportsLiveCommands()) { + deviceSession.sendCommand(command); } else { getDeviceQueue(deviceId).add(command); return false; diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 0e5056e57..b1ea0b8b7 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -68,7 +68,7 @@ public class DeviceManager extends BaseObjectManager implements Identity } @Override - public long addUnknownDevice(String uniqueId) { + public Device addUnknownDevice(String uniqueId) { Device device = new Device(); device.setName(uniqueId); device.setUniqueId(uniqueId); @@ -89,10 +89,10 @@ public class DeviceManager extends BaseObjectManager implements Identity Context.getPermissionsManager().refreshAllExtendedPermissions(); } - return device.getId(); + return device; } catch (StorageException e) { LOGGER.warn("Automatic device registration error", e); - return 0; + return null; } } diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index af6a6ce71..ee386fdfd 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -20,7 +20,7 @@ import org.traccar.model.Position; public interface IdentityManager { - long addUnknownDevice(String uniqueId); + Device addUnknownDevice(String uniqueId); Device getById(long id); diff --git a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java index 3a6af60a1..01d329580 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java @@ -291,7 +291,7 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { if (serviceType == SERVICE_TELEDATA && position.getValid()) { if (useObjectIdAsDeviceId && objectId != 0L) { - deviceSession = getDeviceSession(channel, remoteAddress, true, String.valueOf(objectId)); + deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(objectId)); if (deviceSession != null) { position.setDeviceId(deviceSession.getDeviceId()); } diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 0f89597ce..4b9757874 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -471,7 +471,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { TimeZone timeZone = deviceSession.get(DeviceSession.KEY_TIMEZONE); if (timeZone.getRawOffset() == 0) { timeZone.setRawOffset(offset * 1000); - deviceSession.setTimeZone(timeZone); + deviceSession.set(DeviceSession.KEY_TIMEZONE, timeZone); } } } diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index 8ec47908f..1164d72a1 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -70,8 +70,7 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { JsonArray messages = json.getJsonArray("Messages"); for (int i = 0; i < messages.size(); i++) { JsonObject message = messages.getJsonObject(i); - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, true, message.getString("MobileID")); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, message.getString("MobileID")); if (deviceSession != null) { Position position = new Position(getProtocolName()); diff --git a/src/main/java/org/traccar/session/ActiveDevice.java b/src/main/java/org/traccar/session/ActiveDevice.java deleted file mode 100644 index af19ba55b..000000000 --- a/src/main/java/org/traccar/session/ActiveDevice.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2015 - 2020 Anton Tananaev (anton@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.session; - -import io.netty.channel.Channel; -import io.netty.handler.codec.http.HttpRequestDecoder; -import org.traccar.BasePipelineFactory; -import org.traccar.Protocol; -import org.traccar.model.Command; - -import java.net.SocketAddress; - -public class ActiveDevice { - - private final long deviceId; - private final Protocol protocol; - private final Channel channel; - private final SocketAddress remoteAddress; - private final boolean supportsLiveCommands; - - public ActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - this.deviceId = deviceId; - this.protocol = protocol; - this.channel = channel; - this.remoteAddress = remoteAddress; - supportsLiveCommands = BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) == null; - } - - public Channel getChannel() { - return channel; - } - - public long getDeviceId() { - return deviceId; - } - - public boolean supportsLiveCommands() { - return supportsLiveCommands; - } - - public void sendCommand(Command command) { - protocol.sendDataCommand(channel, remoteAddress, command); - } - -} diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index fbc15b00d..5d8a8c606 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -31,6 +31,7 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.storage.StorageException; +import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Date; import java.util.HashMap; @@ -47,7 +48,9 @@ public class ConnectionManager { private final long deviceTimeout; private final boolean updateDeviceState; - private final Map activeDevices = new ConcurrentHashMap<>(); + private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); + private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); + private final Map> listeners = new ConcurrentHashMap<>(); private final Map timeouts = new ConcurrentHashMap<>(); @@ -59,22 +62,78 @@ public class ConnectionManager { timer = Main.getInjector().getInstance(Timer.class); } - public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - activeDevices.put(deviceId, new ActiveDevice(deviceId, protocol, channel, remoteAddress)); + public DeviceSession getDeviceSession(long deviceId) { + return sessionsByDeviceId.get(deviceId); } - public void removeActiveDevice(Channel channel) { - for (ActiveDevice activeDevice : activeDevices.values()) { - if (activeDevice.getChannel() == channel) { - updateDevice(activeDevice.getDeviceId(), Device.STATUS_OFFLINE, null); - activeDevices.remove(activeDevice.getDeviceId()); - break; + public DeviceSession getDeviceSession( + Protocol protocol, Channel channel, SocketAddress remoteAddress, String... uniqueIds) { + + Endpoint endpoint = new Endpoint(channel, remoteAddress); + Map endpointSessions = sessionsByEndpoint.getOrDefault( + endpoint, new ConcurrentHashMap<>()); + if (uniqueIds.length > 0) { + for (String uniqueId : uniqueIds) { + DeviceSession deviceSession = endpointSessions.get(uniqueId); + if (deviceSession != null) { + return deviceSession; + } } + } else { + return endpointSessions.values().stream().findAny().orElse(null); + } + + Device device = null; + try { + for (String uniqueId : uniqueIds) { + device = Context.getIdentityManager().getByUniqueId(uniqueId); + if (device != null) { + break; + } + } + } catch (Exception e) { + LOGGER.warn("Find device error", e); + } + + if (device == null && Context.getConfig().getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { + device = Context.getIdentityManager().addUnknownDevice(uniqueIds[0]); + } + + if (device != null && !device.getDisabled()) { + DeviceSession oldSession = sessionsByDeviceId.remove(device.getId()); + if (oldSession != null) { + Endpoint oldEndpoint = new Endpoint(oldSession.getChannel(), oldSession.getRemoteAddress()); + Map oldEndpointSessions = sessionsByEndpoint.get(oldEndpoint); + if (oldEndpointSessions.size() > 1) { + oldEndpointSessions.remove(device.getUniqueId()); + } else { + sessionsByEndpoint.remove(oldEndpoint); + } + } + + DeviceSession deviceSession = new DeviceSession( + device.getId(), device.getUniqueId(), protocol, channel, remoteAddress); + endpointSessions.put(device.getUniqueId(), deviceSession); + sessionsByEndpoint.put(endpoint, endpointSessions); + sessionsByDeviceId.put(device.getId(), deviceSession); + + return deviceSession; + } else { + LOGGER.warn((device == null ? "Unknown" : "Disabled") + " device - " + String.join(" ", uniqueIds) + + " (" + ((InetSocketAddress) remoteAddress).getHostString() + ")"); + return null; } } - public ActiveDevice getActiveDevice(long deviceId) { - return activeDevices.get(deviceId); + public void removeDeviceSessions(Channel channel) { + Endpoint endpoint = new Endpoint(channel, channel.remoteAddress()); + Map endpointSessions = sessionsByEndpoint.remove(endpoint); + if (endpointSessions != null) { + for (DeviceSession deviceSession : endpointSessions.values()) { + updateDevice(deviceSession.getDeviceId(), Device.STATUS_OFFLINE, null); + sessionsByDeviceId.remove(deviceSession.getDeviceId()); + } + } } public void updateDevice(final long deviceId, String status, Date time) { diff --git a/src/main/java/org/traccar/session/DeviceSession.java b/src/main/java/org/traccar/session/DeviceSession.java index 0d5b283fe..009f90f5a 100644 --- a/src/main/java/org/traccar/session/DeviceSession.java +++ b/src/main/java/org/traccar/session/DeviceSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,21 +15,57 @@ */ package org.traccar.session; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.HttpRequestDecoder; +import org.traccar.BasePipelineFactory; +import org.traccar.Protocol; +import org.traccar.model.Command; + +import java.net.SocketAddress; import java.util.HashMap; import java.util.Map; public class DeviceSession { private final long deviceId; + private final String uniqueId; + private final Protocol protocol; + private final Channel channel; + private final SocketAddress remoteAddress; - public DeviceSession(long deviceId) { + public DeviceSession( + long deviceId, String uniqueId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { this.deviceId = deviceId; + this.uniqueId = uniqueId; + this.protocol = protocol; + this.channel = channel; + this.remoteAddress = remoteAddress; } public long getDeviceId() { return deviceId; } + public String getUniqueId() { + return uniqueId; + } + + public Channel getChannel() { + return channel; + } + + public SocketAddress getRemoteAddress() { + return remoteAddress; + } + + public boolean supportsLiveCommands() { + return BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) == null; + } + + public void sendCommand(Command command) { + protocol.sendDataCommand(channel, remoteAddress, command); + } + public static final String KEY_TIMEZONE = "timezone"; private final Map locals = new HashMap<>(); diff --git a/src/main/java/org/traccar/session/Endpoint.java b/src/main/java/org/traccar/session/Endpoint.java new file mode 100644 index 000000000..76aac3444 --- /dev/null +++ b/src/main/java/org/traccar/session/Endpoint.java @@ -0,0 +1,58 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.session; + +import io.netty.channel.Channel; + +import java.net.SocketAddress; +import java.util.Objects; + +public class Endpoint { + + private final Channel channel; + private final SocketAddress remoteAddress; + + public Endpoint(Channel channel, SocketAddress remoteAddress) { + this.channel = channel; + this.remoteAddress = remoteAddress; + } + + public Channel getChannel() { + return channel; + } + + public SocketAddress getRemoteAddress() { + return remoteAddress; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Endpoint endpoint = (Endpoint) o; + return channel.equals(endpoint.channel) && remoteAddress.equals(endpoint.remoteAddress); + } + + @Override + public int hashCode() { + return Objects.hash(channel, remoteAddress); + } + +} diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index a33bb2b5d..40ac76601 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,11 +1,22 @@ package org.traccar; +import io.netty.channel.Channel; +import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.traccar.config.Config; import org.traccar.session.ConnectionManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.model.Device; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.TimeZone; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -30,7 +41,21 @@ public class BaseTest { when(identityManager.lookupAttributeInteger(anyLong(), any(), anyInt(), anyBoolean(), anyBoolean())) .thenAnswer(invocation -> invocation.getArguments()[2]); decoder.setIdentityManager(identityManager); - decoder.setConnectionManager(mock(ConnectionManager.class)); + var connectionManager = mock(ConnectionManager.class); + var uniqueIdsProvided = new HashSet(); + when(connectionManager.getDeviceSession(any(), any(), any(), any())).thenAnswer(invocation -> { + var mock = new DeviceSession(1L, "", mock(Protocol.class), mock(Channel.class), mock(SocketAddress.class)); + if (uniqueIdsProvided.isEmpty()) { + if (invocation.getArguments().length > 3) { + uniqueIdsProvided.add(true); + return mock; + } + return null; + } else { + return mock; + } + }); + decoder.setConnectionManager(connectionManager); decoder.setStatisticsManager(mock(StatisticsManager.class)); decoder.setMediaManager(mock(MediaManager.class)); return decoder; -- cgit v1.2.3 From 45b889838238e232295d332b4a6ae81fb112a806 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 30 May 2022 18:43:17 -0700 Subject: Organize imports in tests --- src/test/java/org/traccar/BaseTest.java | 8 +----- .../java/org/traccar/calendar/CalendarTest.java | 9 +++---- src/test/java/org/traccar/config/ConfigTest.java | 2 +- .../java/org/traccar/geocoder/GeocoderTest.java | 4 +-- .../org/traccar/geofence/GeofenceCircleTest.java | 4 +-- .../org/traccar/geofence/GeofencePolygonTest.java | 4 +-- .../org/traccar/geofence/GeofencePolylineTest.java | 4 +-- .../traccar/handler/ComputedAttributesTest.java | 4 +-- .../org/traccar/handler/FilterHandlerTest.java | 5 +++- .../org/traccar/handler/MotionHandlerTest.java | 7 ++--- .../handler/events/AlertEventHandlerTest.java | 12 ++++----- .../events/CommandResultEventHandlerTest.java | 10 ++++---- .../handler/events/IgnitionEventHandlerTest.java | 10 ++++---- .../handler/events/MotionEventHandlerTest.java | 22 ++++++++-------- .../handler/events/OverspeedEventHandlerTest.java | 22 ++++++++-------- .../traccar/protocol/Jt600ProtocolDecoderTest.java | 3 +-- .../traccar/protocol/Jt600ProtocolEncoderTest.java | 4 +-- .../protocol/MegastekProtocolDecoderTest.java | 2 +- .../traccar/protocol/NavisFrameDecoderTest.java | 3 +-- .../traccar/protocol/NavisProtocolDecoderTest.java | 3 +-- .../traccar/protocol/WatchProtocolDecoderTest.java | 5 +++- .../java/org/traccar/reports/ReportUtilsTest.java | 30 +++++++++++----------- 22 files changed, 87 insertions(+), 90 deletions(-) diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 40ac76601..a34524c43 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -1,22 +1,16 @@ package org.traccar; import io.netty.channel.Channel; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; import org.traccar.config.Config; -import org.traccar.session.ConnectionManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.model.Device; +import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; -import java.util.TimeZone; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; diff --git a/src/test/java/org/traccar/calendar/CalendarTest.java b/src/test/java/org/traccar/calendar/CalendarTest.java index 56406d4b8..def67ff76 100644 --- a/src/test/java/org/traccar/calendar/CalendarTest.java +++ b/src/test/java/org/traccar/calendar/CalendarTest.java @@ -1,5 +1,9 @@ package org.traccar.calendar; +import net.fortuna.ical4j.data.ParserException; +import org.junit.Test; +import org.traccar.model.Calendar; + import java.io.IOException; import java.sql.SQLException; import java.text.DateFormat; @@ -7,11 +11,6 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; -import org.junit.Test; -import org.traccar.model.Calendar; - -import net.fortuna.ical4j.data.ParserException; - import static org.junit.Assert.assertTrue; public class CalendarTest { diff --git a/src/test/java/org/traccar/config/ConfigTest.java b/src/test/java/org/traccar/config/ConfigTest.java index 13d0ffb04..8ba6dace6 100644 --- a/src/test/java/org/traccar/config/ConfigTest.java +++ b/src/test/java/org/traccar/config/ConfigTest.java @@ -1,8 +1,8 @@ package org.traccar.config; import org.junit.Test; + import static org.junit.Assert.assertEquals; -import org.traccar.config.Config; public class ConfigTest { diff --git a/src/test/java/org/traccar/geocoder/GeocoderTest.java b/src/test/java/org/traccar/geocoder/GeocoderTest.java index 91431fd6a..6a85777b1 100644 --- a/src/test/java/org/traccar/geocoder/GeocoderTest.java +++ b/src/test/java/org/traccar/geocoder/GeocoderTest.java @@ -1,10 +1,10 @@ package org.traccar.geocoder; -import java.util.Locale; - import org.junit.Ignore; import org.junit.Test; +import java.util.Locale; + import static org.junit.Assert.assertEquals; public class GeocoderTest { diff --git a/src/test/java/org/traccar/geofence/GeofenceCircleTest.java b/src/test/java/org/traccar/geofence/GeofenceCircleTest.java index 259a8fb77..038e4b6d6 100644 --- a/src/test/java/org/traccar/geofence/GeofenceCircleTest.java +++ b/src/test/java/org/traccar/geofence/GeofenceCircleTest.java @@ -1,9 +1,9 @@ package org.traccar.geofence; -import java.text.ParseException; - import org.junit.Test; +import java.text.ParseException; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/org/traccar/geofence/GeofencePolygonTest.java b/src/test/java/org/traccar/geofence/GeofencePolygonTest.java index cc9c46c94..1b8de68ad 100644 --- a/src/test/java/org/traccar/geofence/GeofencePolygonTest.java +++ b/src/test/java/org/traccar/geofence/GeofencePolygonTest.java @@ -1,9 +1,9 @@ package org.traccar.geofence; -import java.text.ParseException; - import org.junit.Test; +import java.text.ParseException; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/org/traccar/geofence/GeofencePolylineTest.java b/src/test/java/org/traccar/geofence/GeofencePolylineTest.java index 1e9dcb7c3..0e8905319 100644 --- a/src/test/java/org/traccar/geofence/GeofencePolylineTest.java +++ b/src/test/java/org/traccar/geofence/GeofencePolylineTest.java @@ -1,9 +1,9 @@ package org.traccar.geofence; -import java.text.ParseException; - import org.junit.Test; +import java.text.ParseException; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/org/traccar/handler/ComputedAttributesTest.java b/src/test/java/org/traccar/handler/ComputedAttributesTest.java index a76d8169b..e3886317c 100644 --- a/src/test/java/org/traccar/handler/ComputedAttributesTest.java +++ b/src/test/java/org/traccar/handler/ComputedAttributesTest.java @@ -1,12 +1,12 @@ package org.traccar.handler; -import java.util.Date; - import org.junit.Test; import org.traccar.config.Config; import org.traccar.model.Attribute; import org.traccar.model.Position; +import java.util.Date; + import static org.junit.Assert.assertEquals; public class ComputedAttributesTest { diff --git a/src/test/java/org/traccar/handler/FilterHandlerTest.java b/src/test/java/org/traccar/handler/FilterHandlerTest.java index 49bbf70b5..10d6768cf 100644 --- a/src/test/java/org/traccar/handler/FilterHandlerTest.java +++ b/src/test/java/org/traccar/handler/FilterHandlerTest.java @@ -9,10 +9,13 @@ import org.traccar.database.DataManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; + import java.util.Date; + import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class FilterHandlerTest extends BaseTest { diff --git a/src/test/java/org/traccar/handler/MotionHandlerTest.java b/src/test/java/org/traccar/handler/MotionHandlerTest.java index fdbd48334..aa73ac60a 100644 --- a/src/test/java/org/traccar/handler/MotionHandlerTest.java +++ b/src/test/java/org/traccar/handler/MotionHandlerTest.java @@ -1,12 +1,13 @@ package org.traccar.handler; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.*; - import org.junit.Test; import org.traccar.model.Position; import org.traccar.reports.model.TripsConfig; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + public class MotionHandlerTest { @Test diff --git a/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java b/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java index 4934695ad..d6cf32ca3 100644 --- a/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java @@ -1,11 +1,5 @@ package org.traccar.handler.events; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.mock; - -import java.util.Map; - import org.junit.Test; import org.traccar.BaseTest; import org.traccar.config.Config; @@ -13,6 +7,12 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; + public class AlertEventHandlerTest extends BaseTest { @Test diff --git a/src/test/java/org/traccar/handler/events/CommandResultEventHandlerTest.java b/src/test/java/org/traccar/handler/events/CommandResultEventHandlerTest.java index 0ccf9f6b4..4997a0e0f 100644 --- a/src/test/java/org/traccar/handler/events/CommandResultEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/CommandResultEventHandlerTest.java @@ -1,15 +1,15 @@ package org.traccar.handler.events; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.Map; - import org.junit.Test; import org.traccar.BaseTest; import org.traccar.model.Event; import org.traccar.model.Position; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + public class CommandResultEventHandlerTest extends BaseTest { @Test diff --git a/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java index f568b6a74..0de80dd70 100644 --- a/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java @@ -1,16 +1,16 @@ package org.traccar.handler.events; -import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.mock; - -import java.util.Map; - import org.junit.Test; import org.traccar.BaseTest; import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import java.util.Map; + +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; + public class IgnitionEventHandlerTest extends BaseTest { @Test diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 8d84e3125..94dab4049 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -1,10 +1,11 @@ package org.traccar.handler.events; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.traccar.BaseTest; +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.reports.model.TripsConfig; +import org.traccar.session.DeviceState; import java.text.DateFormat; import java.text.ParseException; @@ -13,12 +14,11 @@ import java.util.Date; import java.util.Map; import java.util.TimeZone; -import org.junit.Test; -import org.traccar.BaseTest; -import org.traccar.session.DeviceState; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.reports.model.TripsConfig; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; public class MotionEventHandlerTest extends BaseTest { diff --git a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java index 5c4cce1b6..9e86031e8 100644 --- a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java @@ -1,9 +1,12 @@ package org.traccar.handler.events; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import org.junit.Test; +import org.traccar.BaseTest; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.session.DeviceState; import java.text.DateFormat; import java.text.ParseException; @@ -12,13 +15,10 @@ import java.util.Date; import java.util.Map; import java.util.TimeZone; -import org.junit.Test; -import org.traccar.BaseTest; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.session.DeviceState; -import org.traccar.model.Event; -import org.traccar.model.Position; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; public class OverspeedEventHandlerTest extends BaseTest { diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java index c8db31ad0..98c587a81 100644 --- a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -1,8 +1,7 @@ package org.traccar.protocol; -import org.traccar.ProtocolTest; - import org.junit.Test; +import org.traccar.ProtocolTest; public class Jt600ProtocolDecoderTest extends ProtocolTest { diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java index 51cefb962..fdd73b9ce 100644 --- a/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java @@ -1,11 +1,11 @@ package org.traccar.protocol; -import static org.junit.Assert.assertEquals; - import org.junit.Test; import org.traccar.ProtocolTest; import org.traccar.model.Command; +import static org.junit.Assert.assertEquals; + public class Jt600ProtocolEncoderTest extends ProtocolTest { Jt600ProtocolEncoder encoder = new Jt600ProtocolEncoder(null); Command command = new Command(); diff --git a/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java index ea55a8b1c..964c59927 100644 --- a/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MegastekProtocolDecoderTest.java @@ -1,8 +1,8 @@ package org.traccar.protocol; import org.junit.Test; -import org.traccar.model.Position; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class MegastekProtocolDecoderTest extends ProtocolTest { diff --git a/src/test/java/org/traccar/protocol/NavisFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NavisFrameDecoderTest.java index 0ebfeacd2..29327f7e1 100644 --- a/src/test/java/org/traccar/protocol/NavisFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavisFrameDecoderTest.java @@ -1,8 +1,7 @@ package org.traccar.protocol; -import org.traccar.ProtocolTest; - import org.junit.Test; +import org.traccar.ProtocolTest; public class NavisFrameDecoderTest extends ProtocolTest { diff --git a/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java index 5c841b211..960ed1442 100644 --- a/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/NavisProtocolDecoderTest.java @@ -1,8 +1,7 @@ package org.traccar.protocol; -import org.traccar.ProtocolTest; - import org.junit.Test; +import org.traccar.ProtocolTest; public class NavisProtocolDecoderTest extends ProtocolTest { diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 4d908b750..6f6298ffa 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -5,7 +5,10 @@ import org.traccar.ProtocolTest; import org.traccar.database.MediaManager; import org.traccar.model.Position; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class WatchProtocolDecoderTest extends ProtocolTest { diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index b27104f76..be473a341 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -1,12 +1,13 @@ package org.traccar.reports; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import org.junit.Test; +import org.traccar.BaseTest; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; +import org.traccar.model.Position; +import org.traccar.reports.model.StopReport; +import org.traccar.reports.model.TripReport; +import org.traccar.reports.model.TripsConfig; import java.text.DateFormat; import java.text.ParseException; @@ -18,14 +19,13 @@ import java.util.Iterator; import java.util.List; import java.util.TimeZone; -import org.junit.Test; -import org.traccar.BaseTest; -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Position; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.TripReport; -import org.traccar.reports.model.TripsConfig; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class ReportUtilsTest extends BaseTest { -- cgit v1.2.3 From 5032f99c6462ca97f3629abe1faf2f50cc4977fe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 1 Jun 2022 19:07:59 -0700 Subject: New caching system --- .../java/org/traccar/session/cache/CacheKey.java | 57 ++++++ .../org/traccar/session/cache/CacheManager.java | 214 +++++++++++++++++++++ .../java/org/traccar/session/cache/CacheValue.java | 49 +++++ .../java/org/traccar/storage/query/Condition.java | 4 + 4 files changed, 324 insertions(+) create mode 100644 src/main/java/org/traccar/session/cache/CacheKey.java create mode 100644 src/main/java/org/traccar/session/cache/CacheManager.java create mode 100644 src/main/java/org/traccar/session/cache/CacheValue.java diff --git a/src/main/java/org/traccar/session/cache/CacheKey.java b/src/main/java/org/traccar/session/cache/CacheKey.java new file mode 100644 index 000000000..23145e34b --- /dev/null +++ b/src/main/java/org/traccar/session/cache/CacheKey.java @@ -0,0 +1,57 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.session.cache; + +import org.traccar.model.BaseModel; + +import java.util.Objects; + +class CacheKey { + + private final Class clazz; + private final long id; + + CacheKey(BaseModel object) { + this(object.getClass(), object.getId()); + } + + CacheKey(Class clazz, long id) { + this.clazz = clazz; + this.id = id; + } + + public boolean classIs(Class clazz) { + return clazz.equals(this.clazz); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CacheKey cacheKey = (CacheKey) o; + return id == cacheKey.id && Objects.equals(clazz, cacheKey.clazz); + } + + @Override + public int hashCode() { + return Objects.hash(clazz, id); + } + +} diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java new file mode 100644 index 000000000..ae514ce8b --- /dev/null +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -0,0 +1,214 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.session.cache; + +import org.traccar.model.Attribute; +import org.traccar.model.BaseModel; +import org.traccar.model.Command; +import org.traccar.model.Device; +import org.traccar.model.Driver; +import org.traccar.model.Geofence; +import org.traccar.model.Maintenance; +import org.traccar.model.Notification; +import org.traccar.model.Order; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; + +@Singleton +public class CacheManager { + + private static final Collection> CLASSES = Arrays.asList( + Attribute.class, Command.class, Driver.class, Geofence.class, + Maintenance.class, Notification.class, Order.class); + + private final Storage storage; + + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + + private final Map deviceCache = new HashMap<>(); + private final Map, List>> deviceLinks = new HashMap<>(); + + private final Map> userNotifications = new HashMap<>(); + + @Inject + public CacheManager(Storage storage) throws StorageException { + this.storage = storage; + invalidateUsers(); + } + + public T getObject(Class clazz, long id) { + try { + lock.readLock().lock(); + return deviceCache.get(new CacheKey(clazz, id)).getValue(); + } finally { + lock.readLock().unlock(); + } + } + + public List getDeviceObjects(long deviceId, Class clazz) { + try { + lock.readLock().lock(); + return deviceLinks.get(deviceId).get(clazz).stream() + .map(id -> deviceCache.get(new CacheKey(clazz, id)).getValue()) + .collect(Collectors.toList()); + } finally { + lock.readLock().unlock(); + } + } + + public List getUserNotifications(long userId) { + try { + lock.readLock().lock(); + return userNotifications.get(userId); + } finally { + lock.readLock().unlock(); + } + } + + public void addDevice(long deviceId) throws StorageException { + try { + lock.writeLock().lock(); + unsafeAddDevice(deviceId); + } finally { + lock.writeLock().unlock(); + } + } + + public void removeDevice(long deviceId) { + try { + lock.writeLock().lock(); + unsafeRemoveDevice(deviceId); + } finally { + lock.writeLock().unlock(); + } + } + + public void invalidate( + Class clazz, long id) throws StorageException { + invalidate(new CacheKey(clazz, id)); + } + + public void invalidate( + Class clazz1, long id1, + Class clazz2, long id2) throws StorageException { + invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); + } + + private void invalidateUsers() throws StorageException { + Map notifications = new HashMap<>(); + storage.getObjects(Notification.class, new Request(new Columns.All())) + .forEach(notification -> notifications.put(notification.getId(), notification)); + storage.getPermissions(User.class, Notification.class).forEach(permission -> { + long userId = permission.getOwnerId(); + var notification = notifications.get(permission.getPropertyId()); + userNotifications.computeIfAbsent(userId, k -> new LinkedList<>()).add(notification); + }); + } + + private void addObject(long deviceId, BaseModel object) { + deviceCache.computeIfAbsent(new CacheKey(object), k -> new CacheValue(object)).retain(deviceId); + } + + private void unsafeAddDevice(long deviceId) throws StorageException { + Map, List> links = new HashMap<>(); + + addObject(deviceId, storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId)))); + + for (Class clazz : CLASSES) { + var objects = storage.getObjects(clazz, new Request( + new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); + links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toList())); + objects.forEach(object -> addObject(deviceId, object)); + } + + var users = storage.getObjects(User.class, new Request( + new Columns.All(), new Condition.Permission(User.class, Device.class, deviceId))); + links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toList())); + for (var user : users) { + var notifications = storage.getObjects(Notification.class, new Request( + new Columns.All(), new Condition.Permission(User.class, user.getId(), Notification.class))); + notifications.stream() + .filter(Notification::getAlways) + .forEach(object -> { + links.computeIfAbsent(Notification.class, k -> new LinkedList<>()).add(object.getId()); + addObject(deviceId, object); + }); + } + + deviceLinks.put(deviceId, links); + } + + private void unsafeRemoveDevice(long deviceId) { + deviceCache.remove(new CacheKey(Device.class, deviceId)); + deviceLinks.remove(deviceId).forEach((clazz, ids) -> ids.forEach(id -> { + var key = new CacheKey(clazz, id); + deviceCache.computeIfPresent(key, (k, value) -> { + value.release(deviceId); + return value.getReferences().size() > 0 ? value : null; + }); + })); + } + + private void invalidate(CacheKey... keys) throws StorageException { + try { + lock.writeLock().lock(); + unsafeInvalidate(keys); + } finally { + lock.writeLock().unlock(); + } + } + + private void unsafeInvalidate(CacheKey[] keys) throws StorageException { + boolean invalidateUsers = false; + Set linkedDevices = new HashSet<>(); + for (var key : keys) { + if (key.classIs(User.class) || key.classIs(Notification.class)) { + invalidateUsers = true; + } + deviceCache.computeIfPresent(key, (k, value) -> { + linkedDevices.addAll(value.getReferences()); + return value; + }); + } + for (long deviceId : linkedDevices) { + unsafeRemoveDevice(deviceId); + unsafeAddDevice(deviceId); + } + if (invalidateUsers) { + invalidateUsers(); + } + } + +} diff --git a/src/main/java/org/traccar/session/cache/CacheValue.java b/src/main/java/org/traccar/session/cache/CacheValue.java new file mode 100644 index 000000000..9e955dfe5 --- /dev/null +++ b/src/main/java/org/traccar/session/cache/CacheValue.java @@ -0,0 +1,49 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.session.cache; + +import org.traccar.model.BaseModel; + +import java.util.HashSet; +import java.util.Set; + +class CacheValue { + + private final BaseModel value; + private final Set references = new HashSet<>(); + + CacheValue(BaseModel value) { + this.value = value; + } + + public void retain(long deviceId) { + references.add(deviceId); + } + + public void release(long deviceId) { + references.remove(deviceId); + } + + @SuppressWarnings("unchecked") + public T getValue() { + return (T) value; + } + + public Set getReferences() { + return references; + } + +} diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 4cfdc907f..91ede236c 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -165,6 +165,10 @@ public interface Condition { this(ownerClass, ownerId, propertyClass, 0, false); } + public Permission(Class ownerClass, Class propertyClass, long propertyId) { + this(ownerClass, 0, propertyClass, propertyId, false); + } + public Permission excludeGroups() { return new Permission(this.ownerClass, this.ownerId, this.propertyClass, this.propertyId, true); } -- cgit v1.2.3 From 6e1d43d86414281ca562c45488b82808936fc980 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Jun 2022 17:11:17 -0700 Subject: Integrate cache manager --- src/main/java/org/traccar/BaseProtocolDecoder.java | 7 +++++- src/main/java/org/traccar/MainEventHandler.java | 2 +- .../org/traccar/session/ConnectionManager.java | 26 +++++++++++++++++++--- .../org/traccar/session/cache/CacheManager.java | 8 +++++-- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index d6c571b79..71ef686fa 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -30,6 +30,7 @@ import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; +import org.traccar.storage.StorageException; import java.net.InetSocketAddress; import java.net.SocketAddress; @@ -140,7 +141,11 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } public DeviceSession getDeviceSession(Channel channel, SocketAddress remoteAddress, String... uniqueIds) { - return connectionManager.getDeviceSession(protocol, channel, remoteAddress, uniqueIds); + try { + return connectionManager.getDeviceSession(protocol, channel, remoteAddress, uniqueIds); + } catch (StorageException e) { + throw new RuntimeException(e); + } } public void getLastLocation(Position position, Date deviceTime) { diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 0a25b7547..f04307fdb 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -130,7 +130,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName())) { - Context.getConnectionManager().removeDeviceSessions(ctx.channel()); + Context.getConnectionManager().deviceDisconnected(ctx.channel()); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 5d8a8c606..e01a568aa 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -29,6 +29,7 @@ import org.traccar.handler.events.OverspeedEventHandler; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import java.net.InetSocketAddress; @@ -51,6 +52,8 @@ public class ConnectionManager { private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); + private final CacheManager cacheManager; + private final Map> listeners = new ConcurrentHashMap<>(); private final Map timeouts = new ConcurrentHashMap<>(); @@ -60,6 +63,7 @@ public class ConnectionManager { deviceTimeout = Context.getConfig().getLong(Keys.STATUS_TIMEOUT) * 1000; updateDeviceState = Context.getConfig().getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); timer = Main.getInjector().getInstance(Timer.class); + cacheManager = Main.getInjector().getInstance(CacheManager.class); } public DeviceSession getDeviceSession(long deviceId) { @@ -67,7 +71,8 @@ public class ConnectionManager { } public DeviceSession getDeviceSession( - Protocol protocol, Channel channel, SocketAddress remoteAddress, String... uniqueIds) { + Protocol protocol, Channel channel, SocketAddress remoteAddress, + String... uniqueIds) throws StorageException { Endpoint endpoint = new Endpoint(channel, remoteAddress); Map endpointSessions = sessionsByEndpoint.getOrDefault( @@ -116,6 +121,7 @@ public class ConnectionManager { endpointSessions.put(device.getUniqueId(), deviceSession); sessionsByEndpoint.put(endpoint, endpointSessions); sessionsByDeviceId.put(device.getId(), deviceSession); + cacheManager.addDevice(device.getId()); return deviceSession; } else { @@ -125,17 +131,31 @@ public class ConnectionManager { } } - public void removeDeviceSessions(Channel channel) { + public void deviceDisconnected(Channel channel) { Endpoint endpoint = new Endpoint(channel, channel.remoteAddress()); Map endpointSessions = sessionsByEndpoint.remove(endpoint); if (endpointSessions != null) { for (DeviceSession deviceSession : endpointSessions.values()) { updateDevice(deviceSession.getDeviceId(), Device.STATUS_OFFLINE, null); sessionsByDeviceId.remove(deviceSession.getDeviceId()); + cacheManager.removeDevice(deviceSession.getDeviceId()); } } } + public void deviceUnknown(long deviceId) { + updateDevice(deviceId, Device.STATUS_UNKNOWN, null); + DeviceSession deviceSession = sessionsByDeviceId.remove(deviceId); + cacheManager.removeDevice(deviceId); + if (deviceSession != null) { + Endpoint endpoint = new Endpoint(deviceSession.getChannel(), deviceSession.getRemoteAddress()); + sessionsByEndpoint.computeIfPresent(endpoint, (e, sessions) -> { + sessions.remove(deviceSession.getUniqueId()); + return sessions.isEmpty() ? null : sessions; + }); + } + } + public void updateDevice(final long deviceId, String status, Date time) { Device device = Context.getIdentityManager().getById(deviceId); if (device == null) { @@ -181,7 +201,7 @@ public class ConnectionManager { if (status.equals(Device.STATUS_ONLINE)) { timeouts.put(deviceId, timer.newTimeout(timeout1 -> { if (!timeout1.isCancelled()) { - updateDevice(deviceId, Device.STATUS_UNKNOWN, null); + deviceUnknown(deviceId); } }, deviceTimeout, TimeUnit.MILLISECONDS)); } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index ae514ce8b..d019b072b 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -99,7 +99,9 @@ public class CacheManager { public void addDevice(long deviceId) throws StorageException { try { lock.writeLock().lock(); - unsafeAddDevice(deviceId); + if (!deviceLinks.containsKey(deviceId)) { + unsafeAddDevice(deviceId); + } } finally { lock.writeLock().unlock(); } @@ -108,7 +110,9 @@ public class CacheManager { public void removeDevice(long deviceId) { try { lock.writeLock().lock(); - unsafeRemoveDevice(deviceId); + if (deviceLinks.containsKey(deviceId)) { + unsafeRemoveDevice(deviceId); + } } finally { lock.writeLock().unlock(); } -- cgit v1.2.3 From 946b0ebb443aaeb27bcc0e736eda8e929da8738c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Jun 2022 17:22:59 -0700 Subject: Fix permission query --- src/main/java/org/traccar/storage/DatabaseStorage.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index cd82448e1..34ae7c784 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -323,7 +323,6 @@ public class DatabaseStorage extends Storage { result.append(" UNION "); result.append("SELECT DISTINCT "); - result.append(expandDevices ? "devices." : "all_groups."); // TODO handle reverse (e.g. users by device) result.append(outputKey); result.append(" FROM "); result.append(groupStorageName); -- cgit v1.2.3 From 43942f459f456b05c62ea7549123e28fd7560d56 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Jun 2022 17:38:12 -0700 Subject: Inverse user notification cache --- .../java/org/traccar/session/cache/CacheManager.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index d019b072b..f6f04cc36 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -59,7 +59,7 @@ public class CacheManager { private final Map deviceCache = new HashMap<>(); private final Map, List>> deviceLinks = new HashMap<>(); - private final Map> userNotifications = new HashMap<>(); + private final Map> notificationUsers = new HashMap<>(); @Inject public CacheManager(Storage storage) throws StorageException { @@ -87,10 +87,10 @@ public class CacheManager { } } - public List getUserNotifications(long userId) { + public List getNotificationUsers(long notificationId) { try { lock.readLock().lock(); - return userNotifications.get(userId); + return notificationUsers.get(notificationId); } finally { lock.readLock().unlock(); } @@ -130,13 +130,13 @@ public class CacheManager { } private void invalidateUsers() throws StorageException { - Map notifications = new HashMap<>(); - storage.getObjects(Notification.class, new Request(new Columns.All())) - .forEach(notification -> notifications.put(notification.getId(), notification)); + Map users = new HashMap<>(); + storage.getObjects(User.class, new Request(new Columns.All())) + .forEach(user -> users.put(user.getId(), user)); storage.getPermissions(User.class, Notification.class).forEach(permission -> { - long userId = permission.getOwnerId(); - var notification = notifications.get(permission.getPropertyId()); - userNotifications.computeIfAbsent(userId, k -> new LinkedList<>()).add(notification); + long notificationId = permission.getPropertyId();; + var user = users.get(permission.getOwnerId()); + notificationUsers.computeIfAbsent(notificationId, k -> new LinkedList<>()).add(user); }); } -- cgit v1.2.3 From 026dc29deee601d3351274a888a73b434c1addfa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Jun 2022 17:41:10 -0700 Subject: Add position cache --- .../java/org/traccar/session/cache/CacheManager.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index f6f04cc36..273c54c9a 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -24,6 +24,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.Order; +import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -59,6 +60,7 @@ public class CacheManager { private final Map deviceCache = new HashMap<>(); private final Map, List>> deviceLinks = new HashMap<>(); + private final Map devicePositions = new HashMap<>(); private final Map> notificationUsers = new HashMap<>(); @Inject @@ -87,6 +89,15 @@ public class CacheManager { } } + public Position getPosition(long deviceId) { + try { + lock.readLock().lock(); + return devicePositions.get(deviceId); + } finally { + lock.readLock().unlock(); + } + } + public List getNotificationUsers(long notificationId) { try { lock.readLock().lock(); @@ -118,6 +129,15 @@ public class CacheManager { } } + public void updatePosition(Position position) { + try { + lock.writeLock().lock(); + devicePositions.put(position.getDeviceId(), position); + } finally { + lock.writeLock().unlock(); + } + } + public void invalidate( Class clazz, long id) throws StorageException { invalidate(new CacheKey(clazz, id)); -- cgit v1.2.3 From b7119d6fe834d6ece8b80d5774b143e491eb2a93 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 2 Jun 2022 17:46:11 -0700 Subject: Fix style issue --- src/main/java/org/traccar/session/cache/CacheManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 273c54c9a..4669024d3 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -154,7 +154,7 @@ public class CacheManager { storage.getObjects(User.class, new Request(new Columns.All())) .forEach(user -> users.put(user.getId(), user)); storage.getPermissions(User.class, Notification.class).forEach(permission -> { - long notificationId = permission.getPropertyId();; + long notificationId = permission.getPropertyId(); var user = users.get(permission.getOwnerId()); notificationUsers.computeIfAbsent(notificationId, k -> new LinkedList<>()).add(user); }); -- cgit v1.2.3 From ac065e6d945e66870f39c19578694759cd80f552 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Jun 2022 15:30:54 -0700 Subject: Fix permission query issue --- src/main/java/org/traccar/storage/DatabaseStorage.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 34ae7c784..2b9172153 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -299,10 +299,11 @@ public class DatabaseStorage extends Storage { conditionKey = Permission.getKey(condition.getPropertyClass()); } + String storageName = Permission.getStorageName(condition.getOwnerClass(), condition.getPropertyClass()); result.append("SELECT "); - result.append(outputKey); + result.append(storageName).append('.').append(outputKey); result.append(" FROM "); - result.append(Permission.getStorageName(condition.getOwnerClass(), condition.getPropertyClass())); + result.append(storageName); result.append(" WHERE "); result.append(conditionKey); result.append(" = :"); @@ -323,7 +324,7 @@ public class DatabaseStorage extends Storage { result.append(" UNION "); result.append("SELECT DISTINCT "); - result.append(outputKey); + result.append(groupStorageName).append('.').append(outputKey); result.append(" FROM "); result.append(groupStorageName); -- cgit v1.2.3 From 65b0f9c5398ddcb28018cb1963108534c638b1f4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Jun 2022 16:32:02 -0700 Subject: Fix another permission issue --- src/main/java/org/traccar/storage/DatabaseStorage.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 2b9172153..e4e4f3294 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -324,7 +324,10 @@ public class DatabaseStorage extends Storage { result.append(" UNION "); result.append("SELECT DISTINCT "); - result.append(groupStorageName).append('.').append(outputKey); + if (!expandDevices) { + result.append(groupStorageName).append('.'); + } + result.append(outputKey); result.append(" FROM "); result.append(groupStorageName); -- cgit v1.2.3 From 4030d3207c157a3fcee2653c18440898b6b2a2e6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 3 Jun 2022 17:06:30 -0700 Subject: Remove attributes manager --- src/main/java/org/traccar/Context.java | 14 +------- src/main/java/org/traccar/MainModule.java | 6 ---- .../java/org/traccar/api/BaseObjectResource.java | 36 ++++++++++++++----- .../org/traccar/api/ExtendedObjectResource.java | 2 +- .../java/org/traccar/api/SimpleObjectResource.java | 2 +- .../traccar/api/resource/AttributeResource.java | 6 ++-- .../traccar/api/resource/PermissionsResource.java | 40 ++++++++-------------- .../traccar/api/security/PermissionsService.java | 19 ++++------ .../org/traccar/database/AttributesManager.java | 36 ------------------- .../java/org/traccar/database/DataManager.java | 5 +-- .../org/traccar/database/PermissionsManager.java | 25 -------------- .../traccar/handler/ComputedAttributesHandler.java | 11 +++--- src/main/java/org/traccar/model/Permission.java | 16 +++++---- .../java/org/traccar/storage/DatabaseStorage.java | 4 ++- .../java/org/traccar/storage/MemoryStorage.java | 4 ++- src/main/java/org/traccar/storage/Storage.java | 13 ++++--- 16 files changed, 85 insertions(+), 154 deletions(-) delete mode 100644 src/main/java/org/traccar/database/AttributesManager.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 1faa4c9de..4eab36a89 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,7 +23,6 @@ import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.AttributesManager; import org.traccar.database.BaseObjectManager; import org.traccar.database.CalendarManager; import org.traccar.database.CommandsManager; @@ -44,7 +43,6 @@ import org.traccar.database.UsersManager; import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; -import org.traccar.model.Attribute; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Command; @@ -213,12 +211,6 @@ public final class Context { return eventForwarder; } - private static AttributesManager attributesManager; - - public static AttributesManager getAttributesManager() { - return attributesManager; - } - private static DriversManager driversManager; public static DriversManager getDriversManager() { @@ -343,8 +335,6 @@ public final class Context { eventForwarder = new EventForwarder(); } - attributesManager = new AttributesManager(dataManager); - driversManager = new DriversManager(dataManager); commandsManager = new CommandsManager(dataManager, config.getBoolean(Keys.COMMANDS_QUEUEING)); @@ -398,8 +388,6 @@ public final class Context { return (BaseObjectManager) usersManager; } else if (clazz.equals(Calendar.class)) { return (BaseObjectManager) calendarManager; - } else if (clazz.equals(Attribute.class)) { - return (BaseObjectManager) attributesManager; } else if (clazz.equals(Geofence.class)) { return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Driver.class)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 43ca3ba77..f46312221 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -24,7 +24,6 @@ import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.AttributesManager; import org.traccar.database.CalendarManager; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; @@ -130,11 +129,6 @@ public class MainModule extends AbstractModule { return Context.getCalendarManager(); } - @Provides - public static AttributesManager provideAttributesManager() { - return Context.getAttributesManager(); - } - @Provides public static MaintenancesManager provideMaintenancesManager() { return Context.getMaintenancesManager(); diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 07c74449c..d6401dc42 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -66,7 +66,12 @@ public abstract class BaseObjectResource extends BaseResour permissionsService.checkEdit(getUserId(), entity, true); BaseObjectManager manager = Context.getManager(baseClass); - manager.addItem(entity); + if (manager != null) { + manager.addItem(entity); + } else { + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); + } + LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); @@ -87,7 +92,15 @@ public abstract class BaseObjectResource extends BaseResour permissionsService.checkEdit(getUserId(), entity, false); permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); - Context.getManager(baseClass).updateItem(entity); + BaseObjectManager manager = Context.getManager(baseClass); + if (manager != null) { + manager.updateItem(entity); + } else { + storage.updateObject(entity, new Request( + new Columns.Exclude("id"), + new Condition.Equals("id", "id"))); + } + LogAction.edit(getUserId(), entity); if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { @@ -104,15 +117,20 @@ public abstract class BaseObjectResource extends BaseResour permissionsService.checkPermission(baseClass, getUserId(), id); BaseObjectManager manager = Context.getManager(baseClass); - manager.removeItem(id); - LogAction.remove(getUserId(), baseClass, id); - - if (manager instanceof SimpleObjectManager) { - ((SimpleObjectManager) manager).refreshUserItems(); - if (manager instanceof ExtendedObjectManager) { - ((ExtendedObjectManager) manager).refreshExtendedPermissions(); + if (manager != null) { + manager.removeItem(id); + if (manager instanceof SimpleObjectManager) { + ((SimpleObjectManager) manager).refreshUserItems(); + if (manager instanceof ExtendedObjectManager) { + ((ExtendedObjectManager) manager).refreshExtendedPermissions(); + } } + } else { + storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); } + + LogAction.remove(getUserId(), baseClass, id); + if (baseClass.equals(Group.class) || baseClass.equals(Device.class) || baseClass.equals(User.class)) { if (baseClass.equals(Group.class)) { Context.getGroupsManager().refreshItems(); diff --git a/src/main/java/org/traccar/api/ExtendedObjectResource.java b/src/main/java/org/traccar/api/ExtendedObjectResource.java index 41ed3e9d9..8467b46c6 100644 --- a/src/main/java/org/traccar/api/ExtendedObjectResource.java +++ b/src/main/java/org/traccar/api/ExtendedObjectResource.java @@ -44,7 +44,7 @@ public class ExtendedObjectResource extends BaseObjectResou var conditions = new LinkedList(); if (all) { - if (!permissionsService.isAdmin(getUserId())) { + if (permissionsService.notAdmin(getUserId())) { conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); } } else { diff --git a/src/main/java/org/traccar/api/SimpleObjectResource.java b/src/main/java/org/traccar/api/SimpleObjectResource.java index 15a496c5f..4a435ca7d 100644 --- a/src/main/java/org/traccar/api/SimpleObjectResource.java +++ b/src/main/java/org/traccar/api/SimpleObjectResource.java @@ -41,7 +41,7 @@ public class SimpleObjectResource extends BaseObjectResourc var conditions = new LinkedList(); if (all) { - if (!permissionsService.isAdmin(getUserId())) { + if (permissionsService.notAdmin(getUserId())) { conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); } } else { diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index 478b7acfd..fdd0d4f6f 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -67,10 +67,8 @@ public class AttributeResource extends ExtendedObjectResource { throw new IllegalArgumentException("Device has no last position"); } - Object result = new ComputedAttributesHandler( - Context.getConfig(), - Context.getIdentityManager(), - Context.getAttributesManager()).computeAttribute(entity, last); + Object result = new ComputedAttributesHandler(Context.getConfig(), Context.getIdentityManager(), null) + .computeAttribute(entity, last); if (result != null) { switch (entity.getType()) { case "number": diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 7def38919..484c61e66 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,10 +16,11 @@ */ package org.traccar.api.resource; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Set; +import org.traccar.Context; +import org.traccar.api.BaseResource; +import org.traccar.helper.LogAction; +import org.traccar.model.Permission; +import org.traccar.storage.StorageException; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -29,34 +30,21 @@ import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; - -import org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.helper.LogAction; -import org.traccar.model.Device; -import org.traccar.model.Permission; -import org.traccar.model.User; -import org.traccar.storage.StorageException; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; @Path("permissions") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class PermissionsResource extends BaseResource { - private void checkPermission(Permission permission, boolean link) { - if (!link && permission.getOwnerClass().equals(User.class) - && permission.getPropertyClass().equals(Device.class)) { - if (getUserId() != permission.getOwnerId()) { - Context.getPermissionsManager().checkUser(getUserId(), permission.getOwnerId()); - } else { - Context.getPermissionsManager().checkAdmin(getUserId()); - } - } else { - Context.getPermissionsManager().checkPermission( - permission.getOwnerClass(), getUserId(), permission.getOwnerId()); + private void checkPermission(Permission permission, boolean link) throws StorageException { + if (permissionsService.notAdmin(getUserId())) { + permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); + permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); } - Context.getPermissionsManager().checkPermission( - permission.getPropertyClass(), getUserId(), permission.getPropertyId()); } private void checkPermissionTypes(List> entities) { diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index ac687fc1c..9daef355e 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -61,8 +61,8 @@ public class PermissionsService { return user; } - public boolean isAdmin(long userId) throws StorageException { - return getUser(userId).getAdministrator(); + public boolean notAdmin(long userId) throws StorageException { + return !getUser(userId).getAdministrator(); } public void checkAdmin(long userId) throws StorageException, SecurityException { @@ -134,16 +134,11 @@ public class PermissionsService { if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) { var objects = storage.getObjects(clazz, new Request( new Columns.Include("id"), - new Condition.Permission( - User.class, userId, clazz.equals(User.class) ? ManagedUser.class : clazz))); - boolean found = false; - for (var object : objects) { - if (object.getId() == objectId) { - found = true; - break; - } - } - if (!found) { + new Condition.And( + new Condition.Equals("id", "id", objectId), + new Condition.Permission( + User.class, userId, clazz.equals(User.class) ? ManagedUser.class : clazz)))); + if (!objects.isEmpty()) { throw new SecurityException(clazz.getSimpleName() + " access denied"); } } diff --git a/src/main/java/org/traccar/database/AttributesManager.java b/src/main/java/org/traccar/database/AttributesManager.java deleted file mode 100644 index 28816645a..000000000 --- a/src/main/java/org/traccar/database/AttributesManager.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.database; - -import org.traccar.model.Attribute; - -public class AttributesManager extends ExtendedObjectManager { - - public AttributesManager(DataManager dataManager) { - super(dataManager, Attribute.class); - } - - @Override - public void updateCachedItem(Attribute attribute) { - Attribute cachedAttribute = getById(attribute.getId()); - cachedAttribute.setDescription(attribute.getDescription()); - cachedAttribute.setAttribute(attribute.getAttribute()); - cachedAttribute.setExpression(attribute.getExpression()); - cachedAttribute.setType(attribute.getType()); - } - -} diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 9ac808a69..b5966ca9e 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -240,8 +240,9 @@ public class DataManager { return storage.getPermissions(owner, property); } - public void linkObject(Class owner, long ownerId, Class property, long propertyId, boolean link) - throws StorageException { + public void linkObject( + Class owner, long ownerId, + Class property, long propertyId, boolean link) throws StorageException { if (link) { storage.addPermission(new Permission(owner, ownerId, property, propertyId)); } else { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 9a673c784..29bb8a27b 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -18,7 +18,6 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.model.Attribute; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Command; @@ -368,26 +367,8 @@ public class PermissionsManager { if (object.equals(Device.class)) { checkDevice(userId, objectId); - } else if (object.equals(Group.class)) { - checkGroup(userId, objectId); - } else if (object.equals(User.class) || object.equals(ManagedUser.class)) { - checkUser(userId, objectId); - } else if (object.equals(Geofence.class)) { - manager = Context.getGeofenceManager(); - } else if (object.equals(Attribute.class)) { - manager = Context.getAttributesManager(); - } else if (object.equals(Driver.class)) { - manager = Context.getDriversManager(); - } else if (object.equals(Calendar.class)) { - manager = Context.getCalendarManager(); } else if (object.equals(Command.class)) { manager = Context.getCommandsManager(); - } else if (object.equals(Maintenance.class)) { - manager = Context.getMaintenancesManager(); - } else if (object.equals(Notification.class)) { - manager = Context.getNotificationManager(); - } else if (object.equals(Order.class)) { - manager = Context.getOrderManager(); } else { throw new IllegalArgumentException("Unknown object type"); } @@ -409,7 +390,6 @@ public class PermissionsManager { } Context.getCalendarManager().refreshUserItems(); Context.getDriversManager().refreshUserItems(); - Context.getAttributesManager().refreshUserItems(); Context.getCommandsManager().refreshUserItems(); Context.getMaintenancesManager().refreshUserItems(); if (Context.getNotificationManager() != null) { @@ -422,7 +402,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } Context.getDriversManager().refreshExtendedPermissions(); - Context.getAttributesManager().refreshExtendedPermissions(); Context.getCommandsManager().refreshExtendedPermissions(); Context.getMaintenancesManager().refreshExtendedPermissions(); } @@ -439,8 +418,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Driver.class)) { Context.getDriversManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Attribute.class)) { - Context.getAttributesManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Calendar.class)) { Context.getCalendarManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Command.class)) { @@ -458,8 +435,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Driver.class)) { Context.getDriversManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Attribute.class)) { - Context.getAttributesManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Command.class)) { Context.getCommandsManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Maintenance.class)) { diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 9dc170909..bec3d38e0 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -34,11 +34,11 @@ import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.AttributesManager; import org.traccar.database.IdentityManager; import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @@ -48,7 +48,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ComputedAttributesHandler.class); private final IdentityManager identityManager; - private final AttributesManager attributesManager; + private final CacheManager cacheManager; private final JexlEngine engine; @@ -56,9 +56,9 @@ public class ComputedAttributesHandler extends BaseDataHandler { @Inject public ComputedAttributesHandler( - Config config, IdentityManager identityManager, AttributesManager attributesManager) { + Config config, IdentityManager identityManager, CacheManager cacheManager) { this.identityManager = identityManager; - this.attributesManager = attributesManager; + this.cacheManager = cacheManager; engine = new JexlEngine(); engine.setStrict(true); engine.setFunctions(Collections.singletonMap("math", Math.class)); @@ -107,8 +107,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - Collection attributes = attributesManager.getItems( - attributesManager.getAllDeviceItems(position.getDeviceId())); + Collection attributes = cacheManager.getDeviceObjects(position.getDeviceId(), Attribute.class); for (Attribute attribute : attributes) { if (attribute.getAttribute() != null) { Object result = null; diff --git a/src/main/java/org/traccar/model/Permission.java b/src/main/java/org/traccar/model/Permission.java index bace6b7d4..41dfa43e4 100644 --- a/src/main/java/org/traccar/model/Permission.java +++ b/src/main/java/org/traccar/model/Permission.java @@ -31,12 +31,12 @@ import org.traccar.storage.QueryIgnore; public class Permission { - private static final Map> CLASSES = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + private static final Map> CLASSES = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); static { try { for (Class clazz : ClassScanner.findSubclasses(BaseModel.class)) { - CLASSES.put(clazz.getSimpleName(), clazz); + CLASSES.put(clazz.getSimpleName(), (Class) clazz); } } catch (IOException | ReflectiveOperationException | URISyntaxException e) { throw new RuntimeException(e); @@ -45,9 +45,9 @@ public class Permission { private final LinkedHashMap data; - private final Class ownerClass; + private final Class ownerClass; private final long ownerId; - private final Class propertyClass; + private final Class propertyClass; private final long propertyId; public Permission(LinkedHashMap data) { @@ -61,7 +61,9 @@ public class Permission { propertyId = property.getValue(); } - public Permission(Class ownerClass, long ownerId, Class propertyClass, long propertyId) { + public Permission( + Class ownerClass, long ownerId, + Class propertyClass, long propertyId) { this.ownerClass = ownerClass; this.ownerId = ownerId; this.propertyClass = propertyClass; @@ -105,7 +107,7 @@ public class Permission { @QueryIgnore @JsonIgnore - public Class getOwnerClass() { + public Class getOwnerClass() { return ownerClass; } @@ -117,7 +119,7 @@ public class Permission { @QueryIgnore @JsonIgnore - public Class getPropertyClass() { + public Class getPropertyClass() { return propertyClass; } diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index e4e4f3294..91dd6b077 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -15,6 +15,7 @@ */ package org.traccar.storage; +import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.GroupedModel; @@ -116,7 +117,8 @@ public class DatabaseStorage extends Storage { @Override public List getPermissions( - Class ownerClass, long ownerId, Class propertyClass, long propertyId) throws StorageException { + Class ownerClass, long ownerId, + Class propertyClass, long propertyId) throws StorageException { StringBuilder query = new StringBuilder("SELECT * FROM "); query.append(Permission.getStorageName(ownerClass, propertyClass)); var conditions = new LinkedList(); diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java index 71e895428..f19897ff8 100644 --- a/src/main/java/org/traccar/storage/MemoryStorage.java +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -15,6 +15,7 @@ */ package org.traccar.storage; +import org.traccar.model.BaseModel; import org.traccar.model.Pair; import org.traccar.model.Permission; import org.traccar.storage.query.Request; @@ -54,7 +55,8 @@ public class MemoryStorage extends Storage { @Override public List getPermissions( - Class ownerClass, long ownerId, Class propertyClass, long propertyId) { + Class ownerClass, long ownerId, + Class propertyClass, long propertyId) { return getPermissionsSet(ownerClass, propertyClass).stream() .filter(pair -> ownerId == 0 || pair.getFirst().equals(ownerId)) .filter(pair -> propertyId == 0 || pair.getSecond().equals(propertyId)) diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java index 22b5aaedc..62dba0165 100644 --- a/src/main/java/org/traccar/storage/Storage.java +++ b/src/main/java/org/traccar/storage/Storage.java @@ -15,6 +15,7 @@ */ package org.traccar.storage; +import org.traccar.model.BaseModel; import org.traccar.model.Permission; import org.traccar.storage.query.Request; @@ -31,24 +32,28 @@ public abstract class Storage { public abstract void removeObject(Class clazz, Request request) throws StorageException; public abstract List getPermissions( - Class ownerClass, long ownerId, Class propertyClass, long propertyId) throws StorageException; + Class ownerClass, long ownerId, + Class propertyClass, long propertyId) throws StorageException; public abstract void addPermission(Permission permission) throws StorageException; public abstract void removePermission(Permission permission) throws StorageException; public List getPermissions( - Class ownerClass, Class propertyClass) throws StorageException { + Class ownerClass, + Class propertyClass) throws StorageException { return getPermissions(ownerClass, 0, propertyClass, 0); } public List getPermissions( - Class ownerClass, long ownerId, Class propertyClass) throws StorageException { + Class ownerClass, long ownerId, + Class propertyClass) throws StorageException { return getPermissions(ownerClass, ownerId, propertyClass, 0); } public List getPermissions( - Class ownerClass, Class propertyClass, long propertyId) throws StorageException { + Class ownerClass, + Class propertyClass, long propertyId) throws StorageException { return getPermissions(ownerClass, 0, propertyClass, propertyId); } -- cgit v1.2.3 From ec76482c15094a7e04964c67d3011a7e8e1ad6a9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 06:33:02 -0700 Subject: Refactor commands manager --- src/main/java/org/traccar/BaseProtocolDecoder.java | 19 ++- src/main/java/org/traccar/Context.java | 12 -- src/main/java/org/traccar/MainModule.java | 6 + .../org/traccar/api/resource/CommandResource.java | 104 ++++++++++---- .../org/traccar/api/resource/PositionResource.java | 3 +- .../org/traccar/api/resource/ReportResource.java | 21 +-- .../traccar/api/security/PermissionsService.java | 12 +- .../java/org/traccar/database/CommandsManager.java | 149 +++++++-------------- .../java/org/traccar/database/DataManager.java | 13 +- .../org/traccar/database/PermissionsManager.java | 31 ----- src/main/java/org/traccar/model/Server.java | 6 +- src/main/java/org/traccar/model/User.java | 8 +- .../java/org/traccar/model/UserRestrictions.java | 23 ++++ .../traccar/protocol/OsmAndProtocolDecoder.java | 9 +- .../java/org/traccar/storage/DatabaseStorage.java | 16 +++ .../java/org/traccar/storage/query/Condition.java | 16 +++ src/test/java/org/traccar/BaseTest.java | 2 + 17 files changed, 241 insertions(+), 209 deletions(-) create mode 100644 src/main/java/org/traccar/model/UserRestrictions.java diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 71ef686fa..5b3f129de 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -15,7 +15,6 @@ */ package org.traccar; -import com.google.inject.Inject; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.config.Config; @@ -32,6 +31,7 @@ import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; import org.traccar.storage.StorageException; +import javax.inject.Inject; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Collection; @@ -51,6 +51,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private ConnectionManager connectionManager; private StatisticsManager statisticsManager; private MediaManager mediaManager; + private CommandsManager commandsManager; public BaseProtocolDecoder(Protocol protocol) { this.protocol = protocol; @@ -96,6 +97,15 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { this.mediaManager = mediaManager; } + @Inject + public void setCommandsManager(CommandsManager commandsManager) { + this.commandsManager = commandsManager; + } + + public CommandsManager getCommandsManager() { + return commandsManager; + } + public String writeMediaFile(String uniqueId, ByteBuf buf, String extension) { return mediaManager.writeFile(uniqueId, buf, extension); } @@ -204,11 +214,8 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } protected void sendQueuedCommands(Channel channel, SocketAddress remoteAddress, long deviceId) { - CommandsManager commandsManager = Context.getCommandsManager(); - if (commandsManager != null) { - for (Command command : commandsManager.readQueuedCommands(deviceId)) { - protocol.sendDataCommand(channel, remoteAddress, command); - } + for (Command command : commandsManager.readQueuedCommands(deviceId)) { + protocol.sendDataCommand(channel, remoteAddress, command); } } diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 4eab36a89..6ee8344ce 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -25,7 +25,6 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; import org.traccar.database.CalendarManager; -import org.traccar.database.CommandsManager; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; @@ -45,7 +44,6 @@ import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; -import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -217,12 +215,6 @@ public final class Context { return driversManager; } - private static CommandsManager commandsManager; - - public static CommandsManager getCommandsManager() { - return commandsManager; - } - private static MaintenancesManager maintenancesManager; public static MaintenancesManager getMaintenancesManager() { @@ -337,8 +329,6 @@ public final class Context { driversManager = new DriversManager(dataManager); - commandsManager = new CommandsManager(dataManager, config.getBoolean(Keys.COMMANDS_QUEUEING)); - orderManager = new OrderManager(dataManager); } @@ -392,8 +382,6 @@ public final class Context { return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Driver.class)) { return (BaseObjectManager) driversManager; - } else if (clazz.equals(Command.class)) { - return (BaseObjectManager) commandsManager; } else if (clazz.equals(Maintenance.class)) { return (BaseObjectManager) maintenancesManager; } else if (clazz.equals(Notification.class)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index f46312221..7b46656b3 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -60,6 +60,7 @@ import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; import org.traccar.reports.model.TripsConfig; +import org.traccar.sms.SmsManager; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.Storage; @@ -134,6 +135,11 @@ public class MainModule extends AbstractModule { return Context.getMaintenancesManager(); } + @Provides + public static SmsManager provideSmsManager() { + return Context.getSmsManager(); + } + @Singleton @Provides public static Geocoder provideGeocoder(Config config) { diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index a31345246..17bb150f6 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * @@ -17,16 +17,23 @@ */ package org.traccar.api.resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.BaseProtocol; import org.traccar.Context; import org.traccar.api.ExtendedObjectResource; import org.traccar.database.CommandsManager; import org.traccar.model.Command; +import org.traccar.model.Device; +import org.traccar.model.Position; import org.traccar.model.Typed; +import org.traccar.model.UserRestrictions; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -35,40 +42,61 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; @Path("commands") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class CommandResource extends ExtendedObjectResource { + private static final Logger LOGGER = LoggerFactory.getLogger(CommandResource.class); + + @Inject + private CommandsManager commandsManager; + public CommandResource() { super(Command.class); } + private BaseProtocol getDeviceProtocol(long deviceId) throws StorageException { + Position position = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.LatestPositions(deviceId))); + if (position != null) { + return Context.getServerManager().getProtocol(position.getProtocol()); + } else { + return null; + } + } + @GET @Path("send") - public Collection get(@QueryParam("deviceId") long deviceId) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - CommandsManager commandsManager = Context.getCommandsManager(); - Set result = new HashSet<>(commandsManager.getUserItems(getUserId())); - result.retainAll(commandsManager.getSupportedCommands(deviceId)); - return commandsManager.getItems(result); + public Collection get(@QueryParam("deviceId") long deviceId) throws StorageException { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + BaseProtocol protocol = getDeviceProtocol(deviceId); + return get(false, 0, 0, deviceId).stream().filter(command -> { + String type = command.getType(); + if (protocol != null) { + return command.getTextChannel() && protocol.getSupportedTextCommands().contains(type) + || !command.getTextChannel() && protocol.getSupportedDataCommands().contains(type); + } else { + return type.equals(Command.TYPE_CUSTOM); + } + }).collect(Collectors.toList()); } @POST @Path("send") public Response send(Command entity) throws Exception { - Context.getPermissionsManager().checkReadonly(getUserId()); - long deviceId = entity.getDeviceId(); - long id = entity.getId(); - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - if (id != 0) { - Context.getPermissionsManager().checkPermission(Command.class, getUserId(), id); - Context.getPermissionsManager().checkUserDeviceCommand(getUserId(), deviceId, id); - } else { - Context.getPermissionsManager().checkLimitCommands(getUserId()); - } - if (!Context.getCommandsManager().sendCommand(entity)) { + permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getLimitCommands); + permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); + if (!commandsManager.sendCommand(entity)) { return Response.accepted(entity).build(); } return Response.ok(entity).build(); @@ -78,15 +106,33 @@ public class CommandResource extends ExtendedObjectResource { @Path("types") public Collection get( @QueryParam("deviceId") long deviceId, - @QueryParam("protocol") String protocol, - @QueryParam("textChannel") boolean textChannel) { + @QueryParam("textChannel") boolean textChannel) throws StorageException { if (deviceId != 0) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - return Context.getCommandsManager().getCommandTypes(deviceId, textChannel); - } else if (protocol != null) { - return Context.getCommandsManager().getCommandTypes(protocol, textChannel); + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + BaseProtocol protocol = getDeviceProtocol(deviceId); + if (protocol != null) { + if (textChannel) { + return protocol.getSupportedTextCommands().stream().map(Typed::new).collect(Collectors.toList()); + } else { + return protocol.getSupportedDataCommands().stream().map(Typed::new).collect(Collectors.toList()); + } + } else { + return Collections.singletonList(new Typed(Command.TYPE_CUSTOM)); + } } else { - return Context.getCommandsManager().getAllCommandTypes(); + List result = new ArrayList<>(); + Field[] fields = Command.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { + try { + result.add(new Typed(field.get(null).toString())); + } catch (IllegalArgumentException | IllegalAccessException error) { + LOGGER.warn("Get command types error", error); + } + } + } + return result; } } + } diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 941417231..2618a04cb 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -18,6 +18,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.Position; +import org.traccar.model.UserRestrictions; import org.traccar.storage.StorageException; import javax.ws.rs.Consumes; @@ -55,7 +56,7 @@ public class PositionResource extends BaseResource { } else { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); if (from != null && to != null) { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return Context.getDataManager().getPositions(deviceId, from, to); } else { return Collections.singleton(Context.getDeviceManager().getLastPosition(deviceId)); diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 901385d0d..06ccbe4fd 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -42,6 +42,7 @@ import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.UserRestrictions; import org.traccar.reports.Events; import org.traccar.reports.Summary; import org.traccar.reports.Trips; @@ -99,7 +100,7 @@ public class ReportResource extends BaseResource { public Collection getRoute( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); return Route.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -111,7 +112,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); Route.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); @@ -124,7 +125,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); return Events.getObjects(getUserId(), deviceIds, groupIds, types, from, to); } @@ -137,7 +138,7 @@ public class ReportResource extends BaseResource { @QueryParam("type") final List types, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); Events.getExcel(stream, getUserId(), deviceIds, groupIds, types, from, to); @@ -150,7 +151,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily) throws StorageException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); return Summary.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); } @@ -163,7 +164,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily, @QueryParam("mail") boolean mail) throws StorageException, IOException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); Summary.getExcel(stream, getUserId(), deviceIds, groupIds, from, to, daily); @@ -176,7 +177,7 @@ public class ReportResource extends BaseResource { public Collection getTrips( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); return Trips.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -188,7 +189,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); Trips.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); @@ -201,7 +202,7 @@ public class ReportResource extends BaseResource { public Collection getStops( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); return Stops.getObjects(getUserId(), deviceIds, groupIds, from, to); } @@ -213,7 +214,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) throws StorageException, IOException { - permissionsService.checkReports(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); Stops.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 9daef355e..b4a375109 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -25,6 +25,7 @@ import org.traccar.model.ManagedUser; import org.traccar.model.ScheduledModel; import org.traccar.model.Server; import org.traccar.model.User; +import org.traccar.model.UserRestrictions; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -71,10 +72,15 @@ public class PermissionsService { } } - public void checkReports(long userId) throws StorageException, SecurityException { + public interface CheckRestrictionCallback { + boolean denied(UserRestrictions userRestrictions); + } + + public void checkRestriction( + long userId, CheckRestrictionCallback callback) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator() - && (getServer().getDisableReports() || getUser(userId).getDisableReports())) { - throw new SecurityException("Reports are disabled"); + && (callback.denied(getServer()) || callback.denied(getUser(userId)))) { + throw new SecurityException("Operation restricted"); } } diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 57ce0f9a4..d440755f7 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -16,66 +16,75 @@ */ package org.traccar.database; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; +import org.traccar.BaseProtocol; +import org.traccar.ServerManager; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.Command; +import org.traccar.model.Device; +import org.traccar.model.Position; +import org.traccar.session.ConnectionManager; +import org.traccar.session.DeviceSession; +import org.traccar.sms.SmsManager; +import org.traccar.storage.Storage; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.BaseProtocol; -import org.traccar.Context; -import org.traccar.model.Command; -import org.traccar.model.Typed; -import org.traccar.model.Position; -import org.traccar.session.DeviceSession; - -public class CommandsManager extends ExtendedObjectManager { +@Singleton +public class CommandsManager { - private static final Logger LOGGER = LoggerFactory.getLogger(CommandsManager.class); + private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Map> deviceQueues = new ConcurrentHashMap<>(); - private final boolean queueing; + private final Storage storage; + private final ServerManager serverManager; + private final SmsManager smsManager; + private final ConnectionManager connectionManager; - public CommandsManager(DataManager dataManager, boolean queueing) { - super(dataManager, Command.class); - this.queueing = queueing; - } + private final boolean queueing; - public boolean checkDeviceCommand(long deviceId, long commandId) { - return !getAllDeviceItems(deviceId).contains(commandId); + @Inject + public CommandsManager( + Storage storage, ServerManager serverManager, @Nullable SmsManager smsManager, + ConnectionManager connectionManager, Config config) { + this.storage = storage; + this.serverManager = serverManager; + this.smsManager = smsManager; + this.connectionManager = connectionManager; + queueing = config.getBoolean(Keys.COMMANDS_QUEUEING); } public boolean sendCommand(Command command) throws Exception { long deviceId = command.getDeviceId(); - if (command.getId() != 0) { - command = getById(command.getId()).clone(); - command.setDeviceId(deviceId); - } if (command.getTextChannel()) { - Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); - String phone = Context.getIdentityManager().getById(deviceId).getPhone(); - if (lastPosition != null) { - BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - protocol.sendTextCommand(phone, command); + Device device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId))); + Position position = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getPositionId()))); + if (position != null) { + BaseProtocol protocol = serverManager.getProtocol(position.getProtocol()); + protocol.sendTextCommand(device.getPhone(), command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - if (Context.getSmsManager() != null) { - Context.getSmsManager().sendMessageSync(phone, command.getString(Command.KEY_DATA), true); - } else { - throw new RuntimeException("SMS is not enabled"); - } + smsManager.sendMessageSync(device.getPhone(), command.getString(Command.KEY_DATA), true); } else { throw new RuntimeException("Command " + command.getType() + " is not supported"); } } else { - DeviceSession deviceSession = Context.getConnectionManager().getDeviceSession(deviceId); + DeviceSession deviceSession = connectionManager.getDeviceSession(deviceId); if (deviceSession != null) { if (deviceSession.supportsLiveCommands()) { deviceSession.sendCommand(command); @@ -93,76 +102,22 @@ public class CommandsManager extends ExtendedObjectManager { return true; } - public Collection getSupportedCommands(long deviceId) { - List result = new ArrayList<>(); - Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); - for (long commandId : getAllDeviceItems(deviceId)) { - Command command = getById(commandId); - if (lastPosition != null) { - BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - if (command.getTextChannel() && protocol.getSupportedTextCommands().contains(command.getType()) - || !command.getTextChannel() - && protocol.getSupportedDataCommands().contains(command.getType())) { - result.add(commandId); - } - } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - result.add(commandId); - } - } - return result; - } - - public Collection getCommandTypes(long deviceId, boolean textChannel) { - Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); - if (lastPosition != null) { - return getCommandTypes(lastPosition.getProtocol(), textChannel); - } else { - return Collections.singletonList(new Typed(Command.TYPE_CUSTOM)); - } - } - - public Collection getCommandTypes(String protocolName, boolean textChannel) { - List result = new ArrayList<>(); - BaseProtocol protocol = Context.getServerManager().getProtocol(protocolName); - Collection commands; - commands = textChannel ? protocol.getSupportedTextCommands() : protocol.getSupportedDataCommands(); - for (String commandKey : commands) { - result.add(new Typed(commandKey)); - } - return result; - } - - public Collection getAllCommandTypes() { - List result = new ArrayList<>(); - Field[] fields = Command.class.getDeclaredFields(); - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { - try { - result.add(new Typed(field.get(null).toString())); - } catch (IllegalArgumentException | IllegalAccessException error) { - LOGGER.warn("Get command types error", error); - } - } - } - return result; - } - private Queue getDeviceQueue(long deviceId) { Queue deviceQueue; try { - readLock(); + lock.readLock().lock(); deviceQueue = deviceQueues.get(deviceId); } finally { - readUnlock(); + lock.readLock().unlock(); } if (deviceQueue != null) { return deviceQueue; } else { try { - writeLock(); + lock.writeLock().lock(); return deviceQueues.computeIfAbsent(deviceId, key -> new ConcurrentLinkedQueue<>()); } finally { - writeUnlock(); + lock.writeLock().unlock(); } } } @@ -174,10 +129,10 @@ public class CommandsManager extends ExtendedObjectManager { public Collection readQueuedCommands(long deviceId, int count) { Queue deviceQueue; try { - readLock(); + lock.readLock().lock(); deviceQueue = deviceQueues.get(deviceId); } finally { - readUnlock(); + lock.readLock().unlock(); } Collection result = new ArrayList<>(); if (deviceQueue != null) { diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index b5966ca9e..1426daea3 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -50,8 +50,6 @@ import java.lang.reflect.Method; import java.net.URL; import java.util.Collection; import java.util.Date; -import java.util.LinkedList; -import java.util.List; public class DataManager { @@ -205,14 +203,9 @@ public class DataManager { } public Collection getLatestPositions() throws StorageException { - List positions = new LinkedList<>(); - List devices = storage.getObjects(Device.class, new Request(new Columns.Include("positionId"))); - for (Device device : devices) { - positions.addAll(storage.getObjects(Position.class, new Request( - new Columns.All(), - new Condition.Equals("id", "id", device.getPositionId())))); - } - return positions; + return storage.getObjects(Position.class, new Request( + new Columns.All(), + new Condition.LatestPositions())); } public Server getServer() throws StorageException { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 29bb8a27b..4d5c59fcc 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -20,7 +20,6 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; -import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -274,18 +273,6 @@ public class PermissionsManager { } } - public void checkLimitCommands(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getLimitCommands() || getUserLimitCommands(userId))) { - throw new SecurityException("Account has limit sending commands"); - } - } - - public void checkUserDeviceCommand(long userId, long deviceId, long commandId) throws SecurityException { - if (!getUserAdmin(userId) && Context.getCommandsManager().checkDeviceCommand(deviceId, commandId)) { - throw new SecurityException("Command can not be sent to this device"); - } - } - public void checkUserEnabled(long userId) throws SecurityException { User user = getUser(userId); if (user == null) { @@ -367,21 +354,9 @@ public class PermissionsManager { if (object.equals(Device.class)) { checkDevice(userId, objectId); - } else if (object.equals(Command.class)) { - manager = Context.getCommandsManager(); } else { throw new IllegalArgumentException("Unknown object type"); } - - if (manager != null && !manager.checkItemPermission(userId, objectId) && !getUserAdmin(userId)) { - checkManager(userId); - for (long managedUserId : usersManager.getManagedItems(userId)) { - if (manager.checkItemPermission(managedUserId, objectId)) { - return; - } - } - throw new SecurityException("Type " + object + " access denied"); - } } public void refreshAllUsersPermissions() { @@ -390,7 +365,6 @@ public class PermissionsManager { } Context.getCalendarManager().refreshUserItems(); Context.getDriversManager().refreshUserItems(); - Context.getCommandsManager().refreshUserItems(); Context.getMaintenancesManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -402,7 +376,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } Context.getDriversManager().refreshExtendedPermissions(); - Context.getCommandsManager().refreshExtendedPermissions(); Context.getMaintenancesManager().refreshExtendedPermissions(); } @@ -420,8 +393,6 @@ public class PermissionsManager { Context.getDriversManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Calendar.class)) { Context.getCalendarManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Command.class)) { - Context.getCommandsManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Maintenance.class)) { Context.getMaintenancesManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Order.class)) { @@ -435,8 +406,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Driver.class)) { Context.getDriversManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Command.class)) { - Context.getCommandsManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Maintenance.class)) { Context.getMaintenancesManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Order.class)) { diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index b48e84939..7cffd7eac 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -22,7 +22,7 @@ import org.traccar.storage.StorageName; @StorageName("tc_servers") @JsonIgnoreProperties(ignoreUnknown = true) -public class Server extends ExtendedModel { +public class Server extends ExtendedModel implements UserRestrictions { private boolean registration; @@ -36,6 +36,7 @@ public class Server extends ExtendedModel { private boolean readonly; + @Override public boolean getReadonly() { return readonly; } @@ -46,6 +47,7 @@ public class Server extends ExtendedModel { private boolean deviceReadonly; + @Override public boolean getDeviceReadonly() { return deviceReadonly; } @@ -146,6 +148,7 @@ public class Server extends ExtendedModel { private boolean limitCommands; + @Override public boolean getLimitCommands() { return limitCommands; } @@ -156,6 +159,7 @@ public class Server extends ExtendedModel { private boolean disableReports; + @Override public boolean getDisableReports() { return disableReports; } diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 6a67f3276..12fd03d45 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@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,7 @@ import org.traccar.storage.StorageName; import java.util.Date; @StorageName("tc_users") -public class User extends ExtendedModel { +public class User extends ExtendedModel implements UserRestrictions { private String name; @@ -69,6 +69,7 @@ public class User extends ExtendedModel { private boolean readonly; + @Override public boolean getReadonly() { return readonly; } @@ -195,6 +196,7 @@ public class User extends ExtendedModel { private boolean deviceReadonly; + @Override public boolean getDeviceReadonly() { return deviceReadonly; } @@ -222,6 +224,7 @@ public class User extends ExtendedModel { private boolean limitCommands; + @Override public boolean getLimitCommands() { return limitCommands; } @@ -234,6 +237,7 @@ public class User extends ExtendedModel { private boolean disableReports; + @Override public boolean getDisableReports() { return disableReports; } diff --git a/src/main/java/org/traccar/model/UserRestrictions.java b/src/main/java/org/traccar/model/UserRestrictions.java new file mode 100644 index 000000000..2e4e5e363 --- /dev/null +++ b/src/main/java/org/traccar/model/UserRestrictions.java @@ -0,0 +1,23 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.model; + +public interface UserRestrictions { + boolean getReadonly(); + boolean getDeviceReadonly(); + boolean getLimitCommands(); + boolean getDisableReports(); +} diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java index 178ec344f..3574dd2a3 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -21,10 +21,8 @@ import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.Context; import org.traccar.session.DeviceSession; import org.traccar.Protocol; -import org.traccar.database.CommandsManager; import org.traccar.helper.DateUtil; import org.traccar.model.CellTower; import org.traccar.model.Command; @@ -178,11 +176,8 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { if (position.getDeviceId() != 0) { String response = null; - CommandsManager commandsManager = Context.getCommandsManager(); - if (commandsManager != null) { - for (Command command : commandsManager.readQueuedCommands(position.getDeviceId(), 1)) { - response = command.getString(Command.KEY_DATA); - } + for (Command command : getCommandsManager().readQueuedCommands(position.getDeviceId(), 1)) { + response = command.getString(Command.KEY_DATA); } if (response != null) { sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer(response, StandardCharsets.UTF_8)); diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 91dd6b077..fc468182e 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -209,6 +209,11 @@ public class DatabaseStorage extends Storage { } else { results.put(Permission.getKey(condition.getPropertyClass()), condition.getPropertyId()); } + } else if (genericCondition instanceof Condition.LatestPositions) { + var condition = (Condition.LatestPositions) genericCondition; + if (condition.getDeviceId() > 0) { + results.put("deviceId", condition.getDeviceId()); + } } return results; } @@ -262,6 +267,17 @@ public class DatabaseStorage extends Storage { result.append(formatPermissionQuery(condition)); result.append(")"); + } else if (genericCondition instanceof Condition.LatestPositions) { + + var condition = (Condition.LatestPositions) genericCondition; + result.append("id IN ("); + result.append("SELECT positionId FROM "); + result.append(getStorageName(Device.class)); + if (condition.getDeviceId() > 0) { + result.append(" WHERE id = :deviceId"); + } + result.append(")"); + } } return result.toString(); diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 91ede236c..136b0402b 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -196,4 +196,20 @@ public interface Condition { } } + class LatestPositions implements Condition { + private final long deviceId; + + public LatestPositions(long deviceId) { + this.deviceId = deviceId; + } + + public LatestPositions() { + this(0); + } + + public long getDeviceId() { + return deviceId; + } + } + } diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index a34524c43..1652a6694 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -2,6 +2,7 @@ package org.traccar; import io.netty.channel.Channel; import org.traccar.config.Config; +import org.traccar.database.CommandsManager; import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; @@ -52,6 +53,7 @@ public class BaseTest { decoder.setConnectionManager(connectionManager); decoder.setStatisticsManager(mock(StatisticsManager.class)); decoder.setMediaManager(mock(MediaManager.class)); + decoder.setCommandsManager(mock(CommandsManager.class)); return decoder; } -- cgit v1.2.3 From ea22ffb859f8bb8fa0a468af192fef395653d645 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 06:50:50 -0700 Subject: Remove more from context --- src/main/java/org/traccar/Context.java | 16 ---------------- src/main/java/org/traccar/Main.java | 5 +++-- src/main/java/org/traccar/ServerManager.java | 2 ++ .../java/org/traccar/api/resource/CommandResource.java | 7 +++++-- src/main/java/org/traccar/schedule/ScheduleManager.java | 2 ++ .../java/org/traccar/session/cache/CacheManager.java | 3 +-- 6 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 6ee8344ce..eaf973659 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -55,7 +55,6 @@ import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; import org.traccar.reports.model.TripsConfig; -import org.traccar.schedule.ScheduleManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; @@ -149,18 +148,6 @@ public final class Context { return webServer; } - private static ServerManager serverManager; - - public static ServerManager getServerManager() { - return serverManager; - } - - private static ScheduleManager scheduleManager; - - public static ScheduleManager getScheduleManager() { - return scheduleManager; - } - private static BroadcastService broadcastService; public static BroadcastService getBroadcastService() { @@ -316,9 +303,6 @@ public final class Context { initEventsModule(); - serverManager = new ServerManager(); - scheduleManager = new ScheduleManager(); - if (config.hasKey(Keys.BROADCAST_ADDRESS)) { broadcastService = new BroadcastService(config, objectMapper); } diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 016365837..db9892bb9 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -19,6 +19,7 @@ import com.google.inject.Guice; import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.schedule.ScheduleManager; import java.io.File; import java.lang.management.ManagementFactory; @@ -117,9 +118,9 @@ public final class Main { LOGGER.info("Starting server..."); List services = new LinkedList<>(); - services.add(Context.getServerManager()); + services.add(injector.getInstance(ServerManager.class)); services.add(Context.getWebServer()); - services.add(Context.getScheduleManager()); + services.add(injector.getInstance(ScheduleManager.class)); services.add(Context.getBroadcastService()); for (LifecycleObject service : services) { diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 15faf9f2b..a6bb6888c 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -20,6 +20,7 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Keys; import org.traccar.helper.ClassScanner; +import javax.inject.Singleton; import java.io.IOException; import java.net.BindException; import java.net.ConnectException; @@ -29,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +@Singleton public class ServerManager implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(ServerManager.class); diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 17bb150f6..60f1f8eb0 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -20,7 +20,7 @@ package org.traccar.api.resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseProtocol; -import org.traccar.Context; +import org.traccar.ServerManager; import org.traccar.api.ExtendedObjectResource; import org.traccar.database.CommandsManager; import org.traccar.model.Command; @@ -60,6 +60,9 @@ public class CommandResource extends ExtendedObjectResource { @Inject private CommandsManager commandsManager; + @Inject + private ServerManager serverManager; + public CommandResource() { super(Command.class); } @@ -68,7 +71,7 @@ public class CommandResource extends ExtendedObjectResource { Position position = storage.getObject(Position.class, new Request( new Columns.All(), new Condition.LatestPositions(deviceId))); if (position != null) { - return Context.getServerManager().getProtocol(position.getProtocol()); + return serverManager.getProtocol(position.getProtocol()); } else { return null; } diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index 7a3d33b85..154de603a 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -17,9 +17,11 @@ package org.traccar.schedule; import org.traccar.LifecycleObject; +import javax.inject.Singleton; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +@Singleton public class ScheduleManager implements LifecycleObject { private ScheduledExecutorService executor; diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 4669024d3..f2570f77c 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -50,8 +50,7 @@ import java.util.stream.Collectors; public class CacheManager { private static final Collection> CLASSES = Arrays.asList( - Attribute.class, Command.class, Driver.class, Geofence.class, - Maintenance.class, Notification.class, Order.class); + Attribute.class, Driver.class, Geofence.class, Maintenance.class, Notification.class); private final Storage storage; -- cgit v1.2.3 From 89b317968655904749addb96b08dfd4681631331 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 06:53:17 -0700 Subject: Remove order manager --- src/main/java/org/traccar/Context.java | 12 ---------- .../java/org/traccar/database/OrderManager.java | 26 ---------------------- .../org/traccar/database/PermissionsManager.java | 5 ----- .../org/traccar/session/cache/CacheManager.java | 2 -- 4 files changed, 45 deletions(-) delete mode 100644 src/main/java/org/traccar/database/OrderManager.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index eaf973659..97cfb2bf9 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -36,7 +36,6 @@ import org.traccar.database.LdapProvider; import org.traccar.database.MailManager; import org.traccar.database.MaintenancesManager; import org.traccar.database.NotificationManager; -import org.traccar.database.OrderManager; import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; import org.traccar.geocoder.Geocoder; @@ -50,7 +49,6 @@ import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.model.Notification; -import org.traccar.model.Order; import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; @@ -208,12 +206,6 @@ public final class Context { return maintenancesManager; } - private static OrderManager orderManager; - - public static OrderManager getOrderManager() { - return orderManager; - } - private static SmsManager smsManager; public static SmsManager getSmsManager() { @@ -313,8 +305,6 @@ public final class Context { driversManager = new DriversManager(dataManager); - orderManager = new OrderManager(dataManager); - } private static void initEventsModule() { @@ -370,8 +360,6 @@ public final class Context { return (BaseObjectManager) maintenancesManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager) notificationManager; - } else if (clazz.equals(Order.class)) { - return (BaseObjectManager) orderManager; } return null; } diff --git a/src/main/java/org/traccar/database/OrderManager.java b/src/main/java/org/traccar/database/OrderManager.java deleted file mode 100644 index c3253e52f..000000000 --- a/src/main/java/org/traccar/database/OrderManager.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2021 Anton Tananaev (anton@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.database; - -import org.traccar.model.Order; - -public class OrderManager extends ExtendedObjectManager { - - public OrderManager(DataManager dataManager) { - super(dataManager, Order.class); - } - -} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 4d5c59fcc..46e19d380 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -27,7 +27,6 @@ import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; -import org.traccar.model.Order; import org.traccar.model.Permission; import org.traccar.model.Server; import org.traccar.model.User; @@ -395,8 +394,6 @@ public class PermissionsManager { Context.getCalendarManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Maintenance.class)) { Context.getMaintenancesManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Order.class)) { - Context.getOrderManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -408,8 +405,6 @@ public class PermissionsManager { Context.getDriversManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Maintenance.class)) { Context.getMaintenancesManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Order.class)) { - Context.getOrderManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshExtendedPermissions(); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index f2570f77c..aca3df52d 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -17,13 +17,11 @@ package org.traccar.session.cache; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; -import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Notification; -import org.traccar.model.Order; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.storage.Storage; -- cgit v1.2.3 From 4b0c47095c4fdd8d8b6849e36aac2761226b5b7e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 09:48:15 -0700 Subject: Update debug config --- debug.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug.xml b/debug.xml index 58335eced..9851232a8 100644 --- a/debug.xml +++ b/debug.xml @@ -11,7 +11,7 @@ true true - true + false org.h2.Driver jdbc:h2:./target/database -- cgit v1.2.3 From fd84b0dcb86208c2c9c64fbe067cf7d4324892ac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 09:59:13 -0700 Subject: Remove ldap from context --- src/main/java/org/traccar/Context.java | 13 +------------ src/main/java/org/traccar/MainModule.java | 12 +++++++++++- src/main/java/org/traccar/database/DataManager.java | 13 +++++++------ src/main/java/org/traccar/database/LdapProvider.java | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 97cfb2bf9..1aa673077 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -25,14 +25,12 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; import org.traccar.database.CalendarManager; -import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.DriversManager; import org.traccar.database.GeofenceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; -import org.traccar.database.LdapProvider; import org.traccar.database.MailManager; import org.traccar.database.MaintenancesManager; import org.traccar.database.NotificationManager; @@ -53,6 +51,7 @@ import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; import org.traccar.reports.model.TripsConfig; +import org.traccar.session.ConnectionManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; @@ -94,12 +93,6 @@ public final class Context { return dataManager; } - private static LdapProvider ldapProvider; - - public static LdapProvider getLdapProvider() { - return ldapProvider; - } - private static MailManager mailManager; public static MailManager getMailManager() { @@ -263,10 +256,6 @@ public final class Context { dataManager = new DataManager(config); } - if (config.hasKey(Keys.LDAP_URL)) { - ldapProvider = new LdapProvider(config); - } - mailManager = new MailManager(); if (dataManager != null) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 7b46656b3..15b9cefda 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -19,12 +19,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.Scopes; -import com.google.inject.Singleton; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.CalendarManager; +import org.traccar.database.LdapProvider; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; @@ -66,6 +66,7 @@ import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.Storage; import javax.annotation.Nullable; +import javax.inject.Singleton; import javax.ws.rs.client.Client; public class MainModule extends AbstractModule { @@ -140,6 +141,15 @@ public class MainModule extends AbstractModule { return Context.getSmsManager(); } + @Singleton + @Provides + public static LdapProvider provideLdapProvider(Config config) { + if (config.hasKey(Keys.LDAP_URL)) { + return new LdapProvider(config); + } + return null; + } + @Singleton @Provides public static Geocoder provideGeocoder(Config config) { diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 1426daea3..29d70ec32 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -25,6 +25,7 @@ import liquibase.exception.LiquibaseException; import liquibase.resource.FileSystemResourceAccessor; import liquibase.resource.ResourceAccessor; import org.traccar.Context; +import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.BaseModel; @@ -131,12 +132,12 @@ public class DataManager { config.getString(Keys.DATABASE_DRIVER), null, null, null, resourceAccessor); - Liquibase liquibase = new Liquibase( - config.getString(Keys.DATABASE_CHANGELOG), resourceAccessor, database); + String changelog = config.getString(Keys.DATABASE_CHANGELOG); - liquibase.clearCheckSums(); - - liquibase.update(new Contexts()); + try (Liquibase liquibase = new Liquibase(changelog, resourceAccessor, database)) { + liquibase.clearCheckSums(); + liquibase.update(new Contexts()); + } } } @@ -146,7 +147,7 @@ public class DataManager { new Condition.Or( new Condition.Equals("email", "email", email.trim()), new Condition.Equals("login", "email")))); - LdapProvider ldapProvider = Context.getLdapProvider(); + LdapProvider ldapProvider = Main.getInjector().getInstance(LdapProvider.class); if (user != null) { if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) || !forceLdap && user.isPasswordValid(password)) { diff --git a/src/main/java/org/traccar/database/LdapProvider.java b/src/main/java/org/traccar/database/LdapProvider.java index d659a11a1..d517294b8 100644 --- a/src/main/java/org/traccar/database/LdapProvider.java +++ b/src/main/java/org/traccar/database/LdapProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -- cgit v1.2.3 From 8c12ded81c5dce295fcb229c566209d784f55356 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 10:38:49 -0700 Subject: Remove maintenance manager --- src/main/java/org/traccar/Context.java | 13 +---- src/main/java/org/traccar/MainModule.java | 6 --- .../org/traccar/api/resource/ReportResource.java | 4 +- .../traccar/api/security/PermissionsService.java | 4 +- .../org/traccar/database/MaintenancesManager.java | 27 ---------- .../org/traccar/database/NotificationManager.java | 57 ++++++++++------------ .../org/traccar/database/PermissionsManager.java | 7 --- .../handler/events/MaintenanceEventHandler.java | 25 +++------- .../org/traccar/notification/EventForwarder.java | 20 +++++--- .../notification/NotificationFormatter.java | 21 ++++---- .../traccar/notificators/NotificatorFirebase.java | 5 +- .../org/traccar/notificators/NotificatorMail.java | 5 +- .../traccar/notificators/NotificatorPushover.java | 5 +- .../org/traccar/notificators/NotificatorSms.java | 7 ++- .../traccar/notificators/NotificatorTelegram.java | 5 +- src/main/java/org/traccar/reports/Events.java | 34 +++++++------ src/main/java/org/traccar/reports/ReportUtils.java | 16 ++++++ 17 files changed, 117 insertions(+), 144 deletions(-) delete mode 100644 src/main/java/org/traccar/database/MaintenancesManager.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 1aa673077..a833d0c52 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -32,7 +32,6 @@ import org.traccar.database.GeofenceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; import org.traccar.database.MailManager; -import org.traccar.database.MaintenancesManager; import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; @@ -45,7 +44,6 @@ import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Group; -import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.User; import org.traccar.notification.EventForwarder; @@ -193,12 +191,6 @@ public final class Context { return driversManager; } - private static MaintenancesManager maintenancesManager; - - public static MaintenancesManager getMaintenancesManager() { - return maintenancesManager; - } - private static SmsManager smsManager; public static SmsManager getSmsManager() { @@ -289,7 +281,7 @@ public final class Context { } if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - eventForwarder = new EventForwarder(); + eventForwarder = new EventForwarder(config); } driversManager = new DriversManager(dataManager); @@ -300,7 +292,6 @@ public final class Context { geofenceManager = new GeofenceManager(dataManager); calendarManager = new CalendarManager(dataManager); - maintenancesManager = new MaintenancesManager(dataManager); notificationManager = new NotificationManager(dataManager); notificatorManager = new NotificatorManager(); Properties velocityProperties = new Properties(); @@ -345,8 +336,6 @@ public final class Context { return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Driver.class)) { return (BaseObjectManager) driversManager; - } else if (clazz.equals(Maintenance.class)) { - return (BaseObjectManager) maintenancesManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager) notificationManager; } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 15b9cefda..219a8fc11 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,7 +30,6 @@ import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.GeofenceManager; import org.traccar.database.IdentityManager; -import org.traccar.database.MaintenancesManager; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; @@ -131,11 +130,6 @@ public class MainModule extends AbstractModule { return Context.getCalendarManager(); } - @Provides - public static MaintenancesManager provideMaintenancesManager() { - return Context.getMaintenancesManager(); - } - @Provides public static SmsManager provideSmsManager() { return Context.getSmsManager(); diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 06ccbe4fd..a7bbe1067 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -127,7 +127,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - return Events.getObjects(getUserId(), deviceIds, groupIds, types, from, to); + return Events.getObjects(storage, getUserId(), deviceIds, groupIds, types, from, to); } @Path("events") @@ -141,7 +141,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - Events.getExcel(stream, getUserId(), deviceIds, groupIds, types, from, to); + Events.getExcel(stream, storage, getUserId(), deviceIds, groupIds, types, from, to); }); } diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index b4a375109..12a2189e9 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -138,13 +138,13 @@ public class PermissionsService { public void checkPermission( Class clazz, long userId, long objectId) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) { - var objects = storage.getObjects(clazz, new Request( + var object = storage.getObject(clazz, new Request( new Columns.Include("id"), new Condition.And( new Condition.Equals("id", "id", objectId), new Condition.Permission( User.class, userId, clazz.equals(User.class) ? ManagedUser.class : clazz)))); - if (!objects.isEmpty()) { + if (object == null) { throw new SecurityException(clazz.getSimpleName() + " access denied"); } } diff --git a/src/main/java/org/traccar/database/MaintenancesManager.java b/src/main/java/org/traccar/database/MaintenancesManager.java deleted file mode 100644 index 4e266cb78..000000000 --- a/src/main/java/org/traccar/database/MaintenancesManager.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2018 Anton Tananaev (anton@traccar.org) - * Copyright 2018 Andrey Kunitsyn (andrey@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.database; - -import org.traccar.model.Maintenance; - -public class MaintenancesManager extends ExtendedObjectManager { - - public MaintenancesManager(DataManager dataManager) { - super(dataManager, Maintenance.class); - } - -} diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index f358b1d4d..64f3b6775 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -77,42 +77,37 @@ public class NotificationManager extends ExtendedObjectManager { usersToForward = new HashSet<>(); } for (long userId : users) { - if ((event.getGeofenceId() == 0 - || Context.getGeofenceManager().checkItemPermission(userId, event.getGeofenceId())) - && (event.getMaintenanceId() == 0 - || Context.getMaintenancesManager().checkItemPermission(userId, event.getMaintenanceId()))) { - if (usersToForward != null) { - usersToForward.add(userId); - } - final Set notificators = new HashSet<>(); - for (long notificationId : getEffectiveNotifications(userId, deviceId, event.getEventTime())) { - Notification notification = getById(notificationId); - if (getById(notificationId).getType().equals(event.getType())) { - boolean filter = false; - if (event.getType().equals(Event.TYPE_ALARM)) { - String alarmsAttribute = notification.getString("alarms"); - if (alarmsAttribute == null) { - filter = true; - } else { - List alarms = Arrays.asList(alarmsAttribute.split(",")); - filter = !alarms.contains(event.getString(Position.KEY_ALARM)); - } - } - if (!filter) { - notificators.addAll(notification.getNotificatorsTypes()); + if (usersToForward != null) { + usersToForward.add(userId); + } + final Set notificators = new HashSet<>(); + for (long notificationId : getEffectiveNotifications(userId, deviceId, event.getEventTime())) { + Notification notification = getById(notificationId); + if (getById(notificationId).getType().equals(event.getType())) { + boolean filter = false; + if (event.getType().equals(Event.TYPE_ALARM)) { + String alarmsAttribute = notification.getString("alarms"); + if (alarmsAttribute == null) { + filter = true; + } else { + List alarms = Arrays.asList(alarmsAttribute.split(",")); + filter = !alarms.contains(event.getString(Position.KEY_ALARM)); } } + if (!filter) { + notificators.addAll(notification.getNotificatorsTypes()); + } } + } - if (position != null && position.getAddress() == null - && geocodeOnRequest && Context.getGeocoder() != null) { - position.setAddress(Context.getGeocoder() - .getAddress(position.getLatitude(), position.getLongitude(), null)); - } + if (position != null && position.getAddress() == null + && geocodeOnRequest && Context.getGeocoder() != null) { + position.setAddress(Context.getGeocoder() + .getAddress(position.getLatitude(), position.getLongitude(), null)); + } - for (String notificator : notificators) { - Context.getNotificatorManager().getNotificator(notificator).sendAsync(userId, event, position); - } + for (String notificator : notificators) { + Context.getNotificatorManager().getNotificator(notificator).sendAsync(userId, event, position); } } if (Context.getEventForwarder() != null) { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 46e19d380..61b35b380 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -24,7 +24,6 @@ import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Group; -import org.traccar.model.Maintenance; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; import org.traccar.model.Permission; @@ -364,7 +363,6 @@ public class PermissionsManager { } Context.getCalendarManager().refreshUserItems(); Context.getDriversManager().refreshUserItems(); - Context.getMaintenancesManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); } @@ -375,7 +373,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } Context.getDriversManager().refreshExtendedPermissions(); - Context.getMaintenancesManager().refreshExtendedPermissions(); } public void refreshPermissions(Permission permission) { @@ -392,8 +389,6 @@ public class PermissionsManager { Context.getDriversManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Calendar.class)) { Context.getCalendarManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Maintenance.class)) { - Context.getMaintenancesManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -403,8 +398,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Driver.class)) { Context.getDriversManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Maintenance.class)) { - Context.getMaintenancesManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshExtendedPermissions(); diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 5b9ce4316..be3e9bf8d 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -20,41 +20,32 @@ import java.util.HashMap; import java.util.Map; import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; -import org.traccar.database.MaintenancesManager; import org.traccar.model.Event; import org.traccar.model.Maintenance; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @ChannelHandler.Sharable public class MaintenanceEventHandler extends BaseEventHandler { - private final IdentityManager identityManager; - private final MaintenancesManager maintenancesManager; + private final CacheManager cacheManager; @Inject - public MaintenanceEventHandler(IdentityManager identityManager, MaintenancesManager maintenancesManager) { - this.identityManager = identityManager; - this.maintenancesManager = maintenancesManager; + public MaintenanceEventHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Map analyzePosition(Position position) { - if (identityManager.getById(position.getDeviceId()) == null - || !identityManager.isLatestPosition(position)) { - return null; - } - - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); - if (lastPosition == null) { + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) < 0) { return null; } Map events = new HashMap<>(); - for (long maintenanceId : maintenancesManager.getAllDeviceItems(position.getDeviceId())) { - Maintenance maintenance = maintenancesManager.getById(maintenanceId); + for (Maintenance maintenance : cacheManager.getDeviceObjects(position.getDeviceId(), Maintenance.class)) { if (maintenance.getPeriod() != 0) { double oldValue = lastPosition.getDouble(maintenance.getType()); double newValue = position.getDouble(maintenance.getType()); @@ -62,7 +53,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { && (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod()) < (long) ((newValue - maintenance.getStart()) / maintenance.getPeriod())) { Event event = new Event(Event.TYPE_MAINTENANCE, position); - event.setMaintenanceId(maintenanceId); + event.setMaintenanceId(maintenance.getId()); event.set(maintenance.getType(), newValue); events.put(event, position); } diff --git a/src/main/java/org/traccar/notification/EventForwarder.java b/src/main/java/org/traccar/notification/EventForwarder.java index c908fedbd..b0494d74d 100644 --- a/src/main/java/org/traccar/notification/EventForwarder.java +++ b/src/main/java/org/traccar/notification/EventForwarder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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,12 +18,15 @@ package org.traccar.notification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; @@ -39,9 +42,12 @@ public class EventForwarder { private final String url; private final String header; - public EventForwarder() { - url = Context.getConfig().getString(Keys.EVENT_FORWARD_URL); - header = Context.getConfig().getString(Keys.EVENT_FORWARD_HEADERS); + private final CacheManager cacheManager; + + public EventForwarder(Config config) { + url = config.getString(Keys.EVENT_FORWARD_URL); + header = config.getString(Keys.EVENT_FORWARD_HEADERS); + cacheManager = Main.getInjector().getInstance(CacheManager.class); } private static final String KEY_POSITION = "position"; @@ -83,18 +89,18 @@ public class EventForwarder { if (position != null) { data.put(KEY_POSITION, position); } - Device device = Context.getIdentityManager().getById(event.getDeviceId()); + Device device = cacheManager.getObject(Device.class, event.getDeviceId()); if (device != null) { data.put(KEY_DEVICE, device); } if (event.getGeofenceId() != 0) { - Geofence geofence = Context.getGeofenceManager().getById(event.getGeofenceId()); + Geofence geofence = cacheManager.getObject(Geofence.class, event.getGeofenceId()); if (geofence != null) { data.put(KEY_GEOFENCE, geofence); } } if (event.getMaintenanceId() != 0) { - Maintenance maintenance = Context.getMaintenancesManager().getById(event.getMaintenanceId()); + Maintenance maintenance = cacheManager.getObject(Maintenance.class, event.getMaintenanceId()); if (maintenance != null) { data.put(KEY_MAINTENANCE, maintenance); } diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 9a6723a71..107426e06 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,19 +20,23 @@ import org.apache.velocity.VelocityContext; import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Event; +import org.traccar.model.Geofence; +import org.traccar.model.Maintenance; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.reports.ReportUtils; +import org.traccar.session.cache.CacheManager; public final class NotificationFormatter { private NotificationFormatter() { } - public static VelocityContext prepareContext(long userId, Event event, Position position) { + public static NotificationMessage formatMessage( + CacheManager cacheManager, long userId, Event event, Position position, String templatePath) { - User user = Context.getPermissionsManager().getUser(userId); - Device device = Context.getIdentityManager().getById(event.getDeviceId()); + User user = cacheManager.getObject(User.class, userId); + Device device = cacheManager.getObject(Device.class, event.getDeviceId()); VelocityContext velocityContext = TextTemplateFormatter.prepareContext(user); @@ -45,21 +49,16 @@ public final class NotificationFormatter { velocityContext.put("volumeUnit", ReportUtils.getVolumeUnit(userId)); } if (event.getGeofenceId() != 0) { - velocityContext.put("geofence", Context.getGeofenceManager().getById(event.getGeofenceId())); + velocityContext.put("geofence", cacheManager.getObject(Geofence.class, event.getGeofenceId())); } if (event.getMaintenanceId() != 0) { - velocityContext.put("maintenance", Context.getMaintenancesManager().getById(event.getMaintenanceId())); + velocityContext.put("maintenance", cacheManager.getObject(Maintenance.class, event.getMaintenanceId())); } String driverUniqueId = event.getString(Position.KEY_DRIVER_UNIQUE_ID); if (driverUniqueId != null) { velocityContext.put("driver", Context.getDriversManager().getDriverByUniqueId(driverUniqueId)); } - return velocityContext; - } - - public static NotificationMessage formatMessage(long userId, Event event, Position position, String templatePath) { - VelocityContext velocityContext = prepareContext(userId, event, position); return TextTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index f91ec25a0..bcce9a4d8 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -20,12 +20,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationMessage; import org.traccar.notification.NotificationFormatter; +import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -69,7 +71,8 @@ public class NotificatorFirebase extends Notificator { final User user = Context.getPermissionsManager().getUser(userId); if (user.getAttributes().containsKey("notificationTokens")) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); Notification notification = new Notification(); notification.title = shortMessage.getSubject(); diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 9b5637ed8..eb7f399eb 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -17,11 +17,13 @@ package org.traccar.notificators; import org.traccar.Context; +import org.traccar.Main; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.notification.NotificationMessage; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; +import org.traccar.session.cache.CacheManager; import javax.mail.MessagingException; @@ -30,7 +32,8 @@ public final class NotificatorMail extends Notificator { @Override public void sendSync(long userId, Event event, Position position) throws MessageException { try { - NotificationMessage fullMessage = NotificationFormatter.formatMessage(userId, event, position, "full"); + NotificationMessage fullMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "full"); Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 456c2fe4f..73fad9bd2 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -19,12 +19,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import org.traccar.notification.NotificationMessage; +import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -77,7 +79,8 @@ public class NotificatorPushover extends Notificator { return; } - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); Message message = new Message(); message.token = token; diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index fb817b112..09eb65b0c 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -25,6 +25,7 @@ import org.traccar.model.User; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import org.traccar.notification.NotificationMessage; +import org.traccar.session.cache.CacheManager; public final class NotificatorSms extends Notificator { @@ -32,7 +33,8 @@ public final class NotificatorSms extends Notificator { public void sendAsync(long userId, Event event, Position position) { final User user = Context.getPermissionsManager().getUser(userId); if (user.getPhone() != null) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageAsync(user.getPhone(), shortMessage.getBody(), false); @@ -43,7 +45,8 @@ public final class NotificatorSms extends Notificator { public void sendSync(long userId, Event event, Position position) throws MessageException, InterruptedException { final User user = Context.getPermissionsManager().getUser(userId); if (user.getPhone() != null) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageSync(user.getPhone(), shortMessage.getBody(), false); diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 70148110c..a8e69e77d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -20,12 +20,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; import org.traccar.model.User; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.notification.NotificationFormatter; import org.traccar.notification.NotificationMessage; +import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; @@ -99,7 +101,8 @@ public class NotificatorTelegram extends Notificator { @Override public void sendSync(long userId, Event event, Position position) { User user = Context.getPermissionsManager().getUser(userId); - NotificationMessage shortMessage = NotificationFormatter.formatMessage(userId, event, position, "short"); + NotificationMessage shortMessage = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); diff --git a/src/main/java/org/traccar/reports/Events.java b/src/main/java/org/traccar/reports/Events.java index e4b905702..818142b16 100644 --- a/src/main/java/org/traccar/reports/Events.java +++ b/src/main/java/org/traccar/reports/Events.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -34,6 +34,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.reports.model.DeviceReport; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; public final class Events { @@ -41,7 +42,9 @@ public final class Events { private Events() { } - public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, + public static Collection getObjects( + Storage storage, long userId, + Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); @@ -53,9 +56,9 @@ public final class Events { if (all || types.contains(event.getType())) { long geofenceId = event.getGeofenceId(); long maintenanceId = event.getMaintenanceId(); - if ((geofenceId == 0 || Context.getGeofenceManager().checkItemPermission(userId, geofenceId)) + if ((geofenceId == 0 || ReportUtils.getObject(storage, userId, Geofence.class, geofenceId) != null) && (maintenanceId == 0 - || Context.getMaintenancesManager().checkItemPermission(userId, maintenanceId))) { + || ReportUtils.getObject(storage, userId, Maintenance.class, maintenanceId) != null)) { result.add(event); } } @@ -64,8 +67,9 @@ public final class Events { return result; } - public static void getExcel(OutputStream outputStream, - long userId, Collection deviceIds, Collection groupIds, + public static void getExcel( + OutputStream outputStream, Storage storage, long userId, + Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); ArrayList devicesEvents = new ArrayList<>(); @@ -82,20 +86,18 @@ public final class Events { long geofenceId = event.getGeofenceId(); long maintenanceId = event.getMaintenanceId(); if (geofenceId != 0) { - if (Context.getGeofenceManager().checkItemPermission(userId, geofenceId)) { - Geofence geofence = Context.getGeofenceManager().getById(geofenceId); - if (geofence != null) { - geofenceNames.put(geofenceId, geofence.getName()); - } + Geofence geofence = ReportUtils.getObject( + storage, userId, Geofence.class, geofenceId); + if (geofence != null) { + geofenceNames.put(geofenceId, geofence.getName()); } else { iterator.remove(); } } else if (maintenanceId != 0) { - if (Context.getMaintenancesManager().checkItemPermission(userId, maintenanceId)) { - Maintenance maintenance = Context.getMaintenancesManager().getById(maintenanceId); - if (maintenance != null) { - maintenanceNames.put(maintenanceId, maintenance.getName()); - } + Maintenance maintenance = ReportUtils.getObject( + storage, userId, Maintenance.class, maintenanceId); + if (maintenance != null) { + maintenanceNames.put(maintenanceId, maintenance.getName()); } else { iterator.remove(); } diff --git a/src/main/java/org/traccar/reports/ReportUtils.java b/src/main/java/org/traccar/reports/ReportUtils.java index 413d49ad7..98a80a23e 100644 --- a/src/main/java/org/traccar/reports/ReportUtils.java +++ b/src/main/java/org/traccar/reports/ReportUtils.java @@ -31,6 +31,8 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; +import org.traccar.model.BaseModel; +import org.traccar.model.User; import org.traccar.session.DeviceState; import org.traccar.model.Driver; import org.traccar.model.Event; @@ -39,6 +41,11 @@ import org.traccar.reports.model.BaseReport; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; import org.traccar.reports.model.TripsConfig; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import java.io.IOException; import java.io.InputStream; @@ -59,6 +66,15 @@ public final class ReportUtils { private ReportUtils() { } + public static T getObject( + Storage storage, long userId, Class clazz, long objectId) throws StorageException, SecurityException { + return storage.getObject(clazz, new Request( + new Columns.Include("id"), + new Condition.And( + new Condition.Equals("id", "id", objectId), + new Condition.Permission(User.class, userId, clazz)))); + } + public static void checkPeriodLimit(Date from, Date to) { long limit = Context.getConfig().getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; if (limit > 0 && to.getTime() - from.getTime() > limit) { -- cgit v1.2.3 From b45b64ce97113c68ef6118665c4a8b0106249264 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 10:52:23 -0700 Subject: Move common report classes --- src/main/java/org/traccar/Context.java | 2 +- src/main/java/org/traccar/MainModule.java | 2 +- .../java/org/traccar/handler/MotionHandler.java | 2 +- .../traccar/handler/events/MotionEventHandler.java | 4 +- .../notification/NotificationFormatter.java | 2 +- .../notification/TextTemplateFormatter.java | 2 +- src/main/java/org/traccar/reports/Events.java | 1 + src/main/java/org/traccar/reports/ReportUtils.java | 388 --------------------- src/main/java/org/traccar/reports/Route.java | 1 + src/main/java/org/traccar/reports/Stops.java | 1 + src/main/java/org/traccar/reports/Summary.java | 1 + src/main/java/org/traccar/reports/Trips.java | 1 + .../org/traccar/reports/common/ReportUtils.java | 387 ++++++++++++++++++++ .../org/traccar/reports/common/TripsConfig.java | 74 ++++ .../org/traccar/reports/model/TripsConfig.java | 74 ---- .../org/traccar/handler/MotionHandlerTest.java | 2 +- .../handler/events/MotionEventHandlerTest.java | 2 +- .../java/org/traccar/reports/ReportUtilsTest.java | 3 +- 18 files changed, 477 insertions(+), 472 deletions(-) delete mode 100644 src/main/java/org/traccar/reports/ReportUtils.java create mode 100644 src/main/java/org/traccar/reports/common/ReportUtils.java create mode 100644 src/main/java/org/traccar/reports/common/TripsConfig.java delete mode 100644 src/main/java/org/traccar/reports/model/TripsConfig.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index a833d0c52..dde98f505 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -48,7 +48,7 @@ import org.traccar.model.Notification; import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import org.traccar.session.ConnectionManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 219a8fc11..fb70a51c6 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -58,7 +58,7 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import org.traccar.sms.SmsManager; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java index 864eb455d..7b2c04ecf 100644 --- a/src/main/java/org/traccar/handler/MotionHandler.java +++ b/src/main/java/org/traccar/handler/MotionHandler.java @@ -19,7 +19,7 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; import org.traccar.model.Position; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import javax.inject.Inject; diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index e27faf9ce..57d2bc1c5 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -26,8 +26,8 @@ import org.traccar.model.Device; import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.reports.ReportUtils; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.common.TripsConfig; import javax.inject.Inject; diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 107426e06..30a862372 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -24,7 +24,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Position; import org.traccar.model.User; -import org.traccar.reports.ReportUtils; +import org.traccar.reports.common.ReportUtils; import org.traccar.session.cache.CacheManager; public final class NotificationFormatter { diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index b7058c824..469de2d4a 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -24,7 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.model.User; -import org.traccar.reports.ReportUtils; +import org.traccar.reports.common.ReportUtils; import java.io.StringWriter; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/org/traccar/reports/Events.java b/src/main/java/org/traccar/reports/Events.java index 818142b16..c5db305ed 100644 --- a/src/main/java/org/traccar/reports/Events.java +++ b/src/main/java/org/traccar/reports/Events.java @@ -33,6 +33,7 @@ import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReport; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/reports/ReportUtils.java b/src/main/java/org/traccar/reports/ReportUtils.java deleted file mode 100644 index 98a80a23e..000000000 --- a/src/main/java/org/traccar/reports/ReportUtils.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) - * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@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.reports; - -import org.apache.velocity.tools.generic.DateTool; -import org.apache.velocity.tools.generic.NumberTool; -import org.jxls.area.Area; -import org.jxls.builder.xls.XlsCommentAreaBuilder; -import org.jxls.common.CellRef; -import org.jxls.formula.StandardFormulaProcessor; -import org.jxls.transform.Transformer; -import org.jxls.transform.poi.PoiTransformer; -import org.jxls.util.TransformerFactory; -import org.traccar.Context; -import org.traccar.config.Keys; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.BaseModel; -import org.traccar.model.User; -import org.traccar.session.DeviceState; -import org.traccar.model.Driver; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.reports.model.BaseReport; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.TripReport; -import org.traccar.reports.model.TripsConfig; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; - -public final class ReportUtils { - - private ReportUtils() { - } - - public static T getObject( - Storage storage, long userId, Class clazz, long objectId) throws StorageException, SecurityException { - return storage.getObject(clazz, new Request( - new Columns.Include("id"), - new Condition.And( - new Condition.Equals("id", "id", objectId), - new Condition.Permission(User.class, userId, clazz)))); - } - - public static void checkPeriodLimit(Date from, Date to) { - long limit = Context.getConfig().getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; - if (limit > 0 && to.getTime() - from.getTime() > limit) { - throw new IllegalArgumentException("Time period exceeds the limit"); - } - } - - public static String getDistanceUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "distanceUnit", "km"); - } - - public static String getSpeedUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "speedUnit", "kn"); - } - - public static String getVolumeUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "volumeUnit", "ltr"); - } - - public static TimeZone getTimezone(long userId) { - String timezone = (String) Context.getPermissionsManager().lookupAttribute(userId, "timezone", null); - return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); - } - - public static Collection getDeviceList(Collection deviceIds, Collection groupIds) { - Collection result = new LinkedHashSet<>(deviceIds); - for (long groupId : groupIds) { - result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); - } - return result; - } - - public static double calculateDistance(Position firstPosition, Position lastPosition) { - return calculateDistance(firstPosition, lastPosition, true); - } - - public static double calculateDistance(Position firstPosition, Position lastPosition, boolean useOdometer) { - double distance = 0.0; - double firstOdometer = firstPosition.getDouble(Position.KEY_ODOMETER); - double lastOdometer = lastPosition.getDouble(Position.KEY_ODOMETER); - - if (useOdometer && firstOdometer != 0.0 && lastOdometer != 0.0) { - distance = lastOdometer - firstOdometer; - } else if (firstPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE) - && lastPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE)) { - distance = lastPosition.getDouble(Position.KEY_TOTAL_DISTANCE) - - firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE); - } - return distance; - } - - public static double calculateFuel(Position firstPosition, Position lastPosition) { - - if (firstPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null - && lastPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null) { - - BigDecimal value = BigDecimal.valueOf(firstPosition.getDouble(Position.KEY_FUEL_LEVEL) - - lastPosition.getDouble(Position.KEY_FUEL_LEVEL)); - return value.setScale(1, RoundingMode.HALF_EVEN).doubleValue(); - } - return 0; - } - - public static String findDriver(Position firstPosition, Position lastPosition) { - if (firstPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { - return firstPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); - } else if (lastPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { - return lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); - } - return null; - } - - public static String findDriverName(String driverUniqueId) { - if (driverUniqueId != null && Context.getDriversManager() != null) { - Driver driver = Context.getDriversManager().getDriverByUniqueId(driverUniqueId); - if (driver != null) { - return driver.getName(); - } - } - return null; - } - - public static org.jxls.common.Context initializeContext(long userId) { - org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext(); - jxlsContext.putVar("distanceUnit", getDistanceUnit(userId)); - jxlsContext.putVar("speedUnit", getSpeedUnit(userId)); - jxlsContext.putVar("volumeUnit", getVolumeUnit(userId)); - jxlsContext.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); - jxlsContext.putVar("dateTool", new DateTool()); - jxlsContext.putVar("numberTool", new NumberTool()); - jxlsContext.putVar("timezone", getTimezone(userId)); - jxlsContext.putVar("locale", Locale.getDefault()); - jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); - return jxlsContext; - } - - public static void processTemplateWithSheets( - InputStream templateStream, OutputStream targetStream, - org.jxls.common.Context jxlsContext) throws IOException { - - Transformer transformer = TransformerFactory.createTransformer(templateStream, targetStream); - List xlsAreas = new XlsCommentAreaBuilder(transformer).build(); - for (Area xlsArea : xlsAreas) { - xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), jxlsContext); - xlsArea.setFormulaProcessor(new StandardFormulaProcessor()); - xlsArea.processFormulas(); - } - transformer.deleteSheet(xlsAreas.get(0).getStartCellRef().getSheetName()); - transformer.write(); - } - - private static TripReport calculateTrip( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer) { - - Position startTrip = positions.get(startIndex); - Position endTrip = positions.get(endIndex); - - double speedMax = 0; - for (int i = startIndex; i <= endIndex; i++) { - double speed = positions.get(i).getSpeed(); - if (speed > speedMax) { - speedMax = speed; - } - } - - TripReport trip = new TripReport(); - - long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); - long deviceId = startTrip.getDeviceId(); - trip.setDeviceId(deviceId); - trip.setDeviceName(identityManager.getById(deviceId).getName()); - - trip.setStartPositionId(startTrip.getId()); - trip.setStartLat(startTrip.getLatitude()); - trip.setStartLon(startTrip.getLongitude()); - trip.setStartTime(startTrip.getFixTime()); - String startAddress = startTrip.getAddress(); - if (startAddress == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - startAddress = Context.getGeocoder().getAddress(startTrip.getLatitude(), startTrip.getLongitude(), null); - } - trip.setStartAddress(startAddress); - - trip.setEndPositionId(endTrip.getId()); - trip.setEndLat(endTrip.getLatitude()); - trip.setEndLon(endTrip.getLongitude()); - trip.setEndTime(endTrip.getFixTime()); - String endAddress = endTrip.getAddress(); - if (endAddress == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - endAddress = Context.getGeocoder().getAddress(endTrip.getLatitude(), endTrip.getLongitude(), null); - } - trip.setEndAddress(endAddress); - - trip.setDistance(calculateDistance(startTrip, endTrip, !ignoreOdometer)); - trip.setDuration(tripDuration); - if (tripDuration > 0) { - trip.setAverageSpeed(UnitsConverter.knotsFromMps(trip.getDistance() * 1000 / tripDuration)); - } - trip.setMaxSpeed(speedMax); - trip.setSpentFuel(calculateFuel(startTrip, endTrip)); - - trip.setDriverUniqueId(findDriver(startTrip, endTrip)); - trip.setDriverName(findDriverName(trip.getDriverUniqueId())); - - if (!ignoreOdometer - && startTrip.getDouble(Position.KEY_ODOMETER) != 0 - && endTrip.getDouble(Position.KEY_ODOMETER) != 0) { - trip.setStartOdometer(startTrip.getDouble(Position.KEY_ODOMETER)); - trip.setEndOdometer(endTrip.getDouble(Position.KEY_ODOMETER)); - } else { - trip.setStartOdometer(startTrip.getDouble(Position.KEY_TOTAL_DISTANCE)); - trip.setEndOdometer(endTrip.getDouble(Position.KEY_TOTAL_DISTANCE)); - } - - return trip; - } - - private static StopReport calculateStop( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer) { - - Position startStop = positions.get(startIndex); - Position endStop = positions.get(endIndex); - - StopReport stop = new StopReport(); - - long deviceId = startStop.getDeviceId(); - stop.setDeviceId(deviceId); - stop.setDeviceName(identityManager.getById(deviceId).getName()); - - stop.setPositionId(startStop.getId()); - stop.setLatitude(startStop.getLatitude()); - stop.setLongitude(startStop.getLongitude()); - stop.setStartTime(startStop.getFixTime()); - String address = startStop.getAddress(); - if (address == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - address = Context.getGeocoder().getAddress(stop.getLatitude(), stop.getLongitude(), null); - } - stop.setAddress(address); - - stop.setEndTime(endStop.getFixTime()); - - long stopDuration = endStop.getFixTime().getTime() - startStop.getFixTime().getTime(); - stop.setDuration(stopDuration); - stop.setSpentFuel(calculateFuel(startStop, endStop)); - - if (startStop.getAttributes().containsKey(Position.KEY_HOURS) - && endStop.getAttributes().containsKey(Position.KEY_HOURS)) { - stop.setEngineHours(endStop.getLong(Position.KEY_HOURS) - startStop.getLong(Position.KEY_HOURS)); - } - - if (!ignoreOdometer - && startStop.getDouble(Position.KEY_ODOMETER) != 0 - && endStop.getDouble(Position.KEY_ODOMETER) != 0) { - stop.setStartOdometer(startStop.getDouble(Position.KEY_ODOMETER)); - stop.setEndOdometer(endStop.getDouble(Position.KEY_ODOMETER)); - } else { - stop.setStartOdometer(startStop.getDouble(Position.KEY_TOTAL_DISTANCE)); - stop.setEndOdometer(endStop.getDouble(Position.KEY_TOTAL_DISTANCE)); - } - - return stop; - - } - - private static T calculateTripOrStop( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { - - if (reportClass.equals(TripReport.class)) { - return (T) calculateTrip(identityManager, positions, startIndex, endIndex, ignoreOdometer); - } else { - return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); - } - } - - private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig) { - if (tripsConfig.getMinimalNoDataDuration() > 0) { - boolean beforeGap = index < positions.size() - 1 - && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration(); - boolean afterGap = index > 0 - && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() - >= tripsConfig.getMinimalNoDataDuration(); - if (beforeGap || afterGap) { - return false; - } - } - if (positions.get(index).getAttributes().containsKey(Position.KEY_MOTION) - && positions.get(index).getAttributes().get(Position.KEY_MOTION) instanceof Boolean) { - return positions.get(index).getBoolean(Position.KEY_MOTION); - } else { - return positions.get(index).getSpeed() > tripsConfig.getSpeedThreshold(); - } - } - - public static Collection detectTripsAndStops( - IdentityManager identityManager, DeviceManager deviceManager, - Collection positionCollection, - TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) { - - Collection result = new ArrayList<>(); - - ArrayList positions = new ArrayList<>(positionCollection); - if (!positions.isEmpty()) { - boolean trips = reportClass.equals(TripReport.class); - MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); - int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; - int startNoEventIndex = -1; - for (int i = 0; i < positions.size(); i++) { - Map event = motionHandler.updateMotionState(deviceState, positions.get(i), - isMoving(positions, i, tripsConfig)); - if (startEventIndex == -1 - && (trips != deviceState.getMotionState() && deviceState.getMotionPosition() != null - || trips == deviceState.getMotionState() && event != null)) { - startEventIndex = i; - startNoEventIndex = -1; - } else if (trips != deviceState.getMotionState() && startEventIndex != -1 - && deviceState.getMotionPosition() == null && event == null) { - startEventIndex = -1; - } - if (startNoEventIndex == -1 - && (trips == deviceState.getMotionState() && deviceState.getMotionPosition() != null - || trips != deviceState.getMotionState() && event != null)) { - startNoEventIndex = i; - } else if (startNoEventIndex != -1 && deviceState.getMotionPosition() == null && event == null) { - startNoEventIndex = -1; - } - if (startEventIndex != -1 && startNoEventIndex != -1 && event != null - && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop(identityManager, positions, - startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); - startEventIndex = -1; - } - } - if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - result.add(calculateTripOrStop(identityManager, positions, - startEventIndex, startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, - ignoreOdometer, reportClass)); - } - } - - return result; - } - -} diff --git a/src/main/java/org/traccar/reports/Route.java b/src/main/java/org/traccar/reports/Route.java index 4a5edd295..d7745157a 100644 --- a/src/main/java/org/traccar/reports/Route.java +++ b/src/main/java/org/traccar/reports/Route.java @@ -29,6 +29,7 @@ import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReport; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/reports/Stops.java b/src/main/java/org/traccar/reports/Stops.java index 36a4a7549..82eb62f66 100644 --- a/src/main/java/org/traccar/reports/Stops.java +++ b/src/main/java/org/traccar/reports/Stops.java @@ -32,6 +32,7 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReport; import org.traccar.reports.model.StopReport; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java index f00b1ca57..20d80a9f5 100644 --- a/src/main/java/org/traccar/reports/Summary.java +++ b/src/main/java/org/traccar/reports/Summary.java @@ -29,6 +29,7 @@ import org.jxls.util.JxlsHelper; import org.traccar.Context; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReport; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/reports/Trips.java b/src/main/java/org/traccar/reports/Trips.java index 1461b869e..58131debb 100644 --- a/src/main/java/org/traccar/reports/Trips.java +++ b/src/main/java/org/traccar/reports/Trips.java @@ -31,6 +31,7 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReport; import org.traccar.reports.model.TripReport; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java new file mode 100644 index 000000000..27972b453 --- /dev/null +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -0,0 +1,387 @@ +/* + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@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.reports.common; + +import org.apache.velocity.tools.generic.DateTool; +import org.apache.velocity.tools.generic.NumberTool; +import org.jxls.area.Area; +import org.jxls.builder.xls.XlsCommentAreaBuilder; +import org.jxls.common.CellRef; +import org.jxls.formula.StandardFormulaProcessor; +import org.jxls.transform.Transformer; +import org.jxls.transform.poi.PoiTransformer; +import org.jxls.util.TransformerFactory; +import org.traccar.Context; +import org.traccar.config.Keys; +import org.traccar.database.DeviceManager; +import org.traccar.database.IdentityManager; +import org.traccar.handler.events.MotionEventHandler; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.BaseModel; +import org.traccar.model.User; +import org.traccar.session.DeviceState; +import org.traccar.model.Driver; +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.reports.model.BaseReport; +import org.traccar.reports.model.StopReport; +import org.traccar.reports.model.TripReport; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +public final class ReportUtils { + + private ReportUtils() { + } + + public static T getObject( + Storage storage, long userId, Class clazz, long objectId) throws StorageException, SecurityException { + return storage.getObject(clazz, new Request( + new Columns.Include("id"), + new Condition.And( + new Condition.Equals("id", "id", objectId), + new Condition.Permission(User.class, userId, clazz)))); + } + + public static void checkPeriodLimit(Date from, Date to) { + long limit = Context.getConfig().getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; + if (limit > 0 && to.getTime() - from.getTime() > limit) { + throw new IllegalArgumentException("Time period exceeds the limit"); + } + } + + public static String getDistanceUnit(long userId) { + return (String) Context.getPermissionsManager().lookupAttribute(userId, "distanceUnit", "km"); + } + + public static String getSpeedUnit(long userId) { + return (String) Context.getPermissionsManager().lookupAttribute(userId, "speedUnit", "kn"); + } + + public static String getVolumeUnit(long userId) { + return (String) Context.getPermissionsManager().lookupAttribute(userId, "volumeUnit", "ltr"); + } + + public static TimeZone getTimezone(long userId) { + String timezone = (String) Context.getPermissionsManager().lookupAttribute(userId, "timezone", null); + return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); + } + + public static Collection getDeviceList(Collection deviceIds, Collection groupIds) { + Collection result = new LinkedHashSet<>(deviceIds); + for (long groupId : groupIds) { + result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); + } + return result; + } + + public static double calculateDistance(Position firstPosition, Position lastPosition) { + return calculateDistance(firstPosition, lastPosition, true); + } + + public static double calculateDistance(Position firstPosition, Position lastPosition, boolean useOdometer) { + double distance = 0.0; + double firstOdometer = firstPosition.getDouble(Position.KEY_ODOMETER); + double lastOdometer = lastPosition.getDouble(Position.KEY_ODOMETER); + + if (useOdometer && firstOdometer != 0.0 && lastOdometer != 0.0) { + distance = lastOdometer - firstOdometer; + } else if (firstPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE) + && lastPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE)) { + distance = lastPosition.getDouble(Position.KEY_TOTAL_DISTANCE) + - firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE); + } + return distance; + } + + public static double calculateFuel(Position firstPosition, Position lastPosition) { + + if (firstPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null + && lastPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null) { + + BigDecimal value = BigDecimal.valueOf(firstPosition.getDouble(Position.KEY_FUEL_LEVEL) + - lastPosition.getDouble(Position.KEY_FUEL_LEVEL)); + return value.setScale(1, RoundingMode.HALF_EVEN).doubleValue(); + } + return 0; + } + + public static String findDriver(Position firstPosition, Position lastPosition) { + if (firstPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { + return firstPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); + } else if (lastPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { + return lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); + } + return null; + } + + public static String findDriverName(String driverUniqueId) { + if (driverUniqueId != null && Context.getDriversManager() != null) { + Driver driver = Context.getDriversManager().getDriverByUniqueId(driverUniqueId); + if (driver != null) { + return driver.getName(); + } + } + return null; + } + + public static org.jxls.common.Context initializeContext(long userId) { + org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext(); + jxlsContext.putVar("distanceUnit", getDistanceUnit(userId)); + jxlsContext.putVar("speedUnit", getSpeedUnit(userId)); + jxlsContext.putVar("volumeUnit", getVolumeUnit(userId)); + jxlsContext.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); + jxlsContext.putVar("dateTool", new DateTool()); + jxlsContext.putVar("numberTool", new NumberTool()); + jxlsContext.putVar("timezone", getTimezone(userId)); + jxlsContext.putVar("locale", Locale.getDefault()); + jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); + return jxlsContext; + } + + public static void processTemplateWithSheets( + InputStream templateStream, OutputStream targetStream, + org.jxls.common.Context jxlsContext) throws IOException { + + Transformer transformer = TransformerFactory.createTransformer(templateStream, targetStream); + List xlsAreas = new XlsCommentAreaBuilder(transformer).build(); + for (Area xlsArea : xlsAreas) { + xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), jxlsContext); + xlsArea.setFormulaProcessor(new StandardFormulaProcessor()); + xlsArea.processFormulas(); + } + transformer.deleteSheet(xlsAreas.get(0).getStartCellRef().getSheetName()); + transformer.write(); + } + + private static TripReport calculateTrip( + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer) { + + Position startTrip = positions.get(startIndex); + Position endTrip = positions.get(endIndex); + + double speedMax = 0; + for (int i = startIndex; i <= endIndex; i++) { + double speed = positions.get(i).getSpeed(); + if (speed > speedMax) { + speedMax = speed; + } + } + + TripReport trip = new TripReport(); + + long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); + long deviceId = startTrip.getDeviceId(); + trip.setDeviceId(deviceId); + trip.setDeviceName(identityManager.getById(deviceId).getName()); + + trip.setStartPositionId(startTrip.getId()); + trip.setStartLat(startTrip.getLatitude()); + trip.setStartLon(startTrip.getLongitude()); + trip.setStartTime(startTrip.getFixTime()); + String startAddress = startTrip.getAddress(); + if (startAddress == null && Context.getGeocoder() != null + && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { + startAddress = Context.getGeocoder().getAddress(startTrip.getLatitude(), startTrip.getLongitude(), null); + } + trip.setStartAddress(startAddress); + + trip.setEndPositionId(endTrip.getId()); + trip.setEndLat(endTrip.getLatitude()); + trip.setEndLon(endTrip.getLongitude()); + trip.setEndTime(endTrip.getFixTime()); + String endAddress = endTrip.getAddress(); + if (endAddress == null && Context.getGeocoder() != null + && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { + endAddress = Context.getGeocoder().getAddress(endTrip.getLatitude(), endTrip.getLongitude(), null); + } + trip.setEndAddress(endAddress); + + trip.setDistance(calculateDistance(startTrip, endTrip, !ignoreOdometer)); + trip.setDuration(tripDuration); + if (tripDuration > 0) { + trip.setAverageSpeed(UnitsConverter.knotsFromMps(trip.getDistance() * 1000 / tripDuration)); + } + trip.setMaxSpeed(speedMax); + trip.setSpentFuel(calculateFuel(startTrip, endTrip)); + + trip.setDriverUniqueId(findDriver(startTrip, endTrip)); + trip.setDriverName(findDriverName(trip.getDriverUniqueId())); + + if (!ignoreOdometer + && startTrip.getDouble(Position.KEY_ODOMETER) != 0 + && endTrip.getDouble(Position.KEY_ODOMETER) != 0) { + trip.setStartOdometer(startTrip.getDouble(Position.KEY_ODOMETER)); + trip.setEndOdometer(endTrip.getDouble(Position.KEY_ODOMETER)); + } else { + trip.setStartOdometer(startTrip.getDouble(Position.KEY_TOTAL_DISTANCE)); + trip.setEndOdometer(endTrip.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + + return trip; + } + + private static StopReport calculateStop( + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer) { + + Position startStop = positions.get(startIndex); + Position endStop = positions.get(endIndex); + + StopReport stop = new StopReport(); + + long deviceId = startStop.getDeviceId(); + stop.setDeviceId(deviceId); + stop.setDeviceName(identityManager.getById(deviceId).getName()); + + stop.setPositionId(startStop.getId()); + stop.setLatitude(startStop.getLatitude()); + stop.setLongitude(startStop.getLongitude()); + stop.setStartTime(startStop.getFixTime()); + String address = startStop.getAddress(); + if (address == null && Context.getGeocoder() != null + && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { + address = Context.getGeocoder().getAddress(stop.getLatitude(), stop.getLongitude(), null); + } + stop.setAddress(address); + + stop.setEndTime(endStop.getFixTime()); + + long stopDuration = endStop.getFixTime().getTime() - startStop.getFixTime().getTime(); + stop.setDuration(stopDuration); + stop.setSpentFuel(calculateFuel(startStop, endStop)); + + if (startStop.getAttributes().containsKey(Position.KEY_HOURS) + && endStop.getAttributes().containsKey(Position.KEY_HOURS)) { + stop.setEngineHours(endStop.getLong(Position.KEY_HOURS) - startStop.getLong(Position.KEY_HOURS)); + } + + if (!ignoreOdometer + && startStop.getDouble(Position.KEY_ODOMETER) != 0 + && endStop.getDouble(Position.KEY_ODOMETER) != 0) { + stop.setStartOdometer(startStop.getDouble(Position.KEY_ODOMETER)); + stop.setEndOdometer(endStop.getDouble(Position.KEY_ODOMETER)); + } else { + stop.setStartOdometer(startStop.getDouble(Position.KEY_TOTAL_DISTANCE)); + stop.setEndOdometer(endStop.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + + return stop; + + } + + private static T calculateTripOrStop( + IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { + + if (reportClass.equals(TripReport.class)) { + return (T) calculateTrip(identityManager, positions, startIndex, endIndex, ignoreOdometer); + } else { + return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); + } + } + + private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig) { + if (tripsConfig.getMinimalNoDataDuration() > 0) { + boolean beforeGap = index < positions.size() - 1 + && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration(); + boolean afterGap = index > 0 + && positions.get(index).getFixTime().getTime() - positions.get(index - 1).getFixTime().getTime() + >= tripsConfig.getMinimalNoDataDuration(); + if (beforeGap || afterGap) { + return false; + } + } + if (positions.get(index).getAttributes().containsKey(Position.KEY_MOTION) + && positions.get(index).getAttributes().get(Position.KEY_MOTION) instanceof Boolean) { + return positions.get(index).getBoolean(Position.KEY_MOTION); + } else { + return positions.get(index).getSpeed() > tripsConfig.getSpeedThreshold(); + } + } + + public static Collection detectTripsAndStops( + IdentityManager identityManager, DeviceManager deviceManager, + Collection positionCollection, + TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) { + + Collection result = new ArrayList<>(); + + ArrayList positions = new ArrayList<>(positionCollection); + if (!positions.isEmpty()) { + boolean trips = reportClass.equals(TripReport.class); + MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); + int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; + int startNoEventIndex = -1; + for (int i = 0; i < positions.size(); i++) { + Map event = motionHandler.updateMotionState(deviceState, positions.get(i), + isMoving(positions, i, tripsConfig)); + if (startEventIndex == -1 + && (trips != deviceState.getMotionState() && deviceState.getMotionPosition() != null + || trips == deviceState.getMotionState() && event != null)) { + startEventIndex = i; + startNoEventIndex = -1; + } else if (trips != deviceState.getMotionState() && startEventIndex != -1 + && deviceState.getMotionPosition() == null && event == null) { + startEventIndex = -1; + } + if (startNoEventIndex == -1 + && (trips == deviceState.getMotionState() && deviceState.getMotionPosition() != null + || trips != deviceState.getMotionState() && event != null)) { + startNoEventIndex = i; + } else if (startNoEventIndex != -1 && deviceState.getMotionPosition() == null && event == null) { + startNoEventIndex = -1; + } + if (startEventIndex != -1 && startNoEventIndex != -1 && event != null + && trips != deviceState.getMotionState()) { + result.add(calculateTripOrStop(identityManager, positions, + startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); + startEventIndex = -1; + } + } + if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { + result.add(calculateTripOrStop(identityManager, positions, + startEventIndex, startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, + ignoreOdometer, reportClass)); + } + } + + return result; + } + +} diff --git a/src/main/java/org/traccar/reports/common/TripsConfig.java b/src/main/java/org/traccar/reports/common/TripsConfig.java new file mode 100644 index 000000000..9a7cebafb --- /dev/null +++ b/src/main/java/org/traccar/reports/common/TripsConfig.java @@ -0,0 +1,74 @@ +/* + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@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.reports.common; + +public class TripsConfig { + + public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, + long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { + this.minimalTripDistance = minimalTripDistance; + this.minimalTripDuration = minimalTripDuration; + this.minimalParkingDuration = minimalParkingDuration; + this.minimalNoDataDuration = minimalNoDataDuration; + this.useIgnition = useIgnition; + this.processInvalidPositions = processInvalidPositions; + this.speedThreshold = speedThreshold; + } + + private final double minimalTripDistance; + + public double getMinimalTripDistance() { + return minimalTripDistance; + } + + private final long minimalTripDuration; + + public long getMinimalTripDuration() { + return minimalTripDuration; + } + + private final long minimalParkingDuration; + + public long getMinimalParkingDuration() { + return minimalParkingDuration; + } + + private final long minimalNoDataDuration; + + public long getMinimalNoDataDuration() { + return minimalNoDataDuration; + } + + private final boolean useIgnition; + + public boolean getUseIgnition() { + return useIgnition; + } + + private final boolean processInvalidPositions; + + public boolean getProcessInvalidPositions() { + return processInvalidPositions; + } + + private final double speedThreshold; + + public double getSpeedThreshold() { + return speedThreshold; + } + +} diff --git a/src/main/java/org/traccar/reports/model/TripsConfig.java b/src/main/java/org/traccar/reports/model/TripsConfig.java deleted file mode 100644 index 34c445f8b..000000000 --- a/src/main/java/org/traccar/reports/model/TripsConfig.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.reports.model; - -public class TripsConfig { - - public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, - long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { - this.minimalTripDistance = minimalTripDistance; - this.minimalTripDuration = minimalTripDuration; - this.minimalParkingDuration = minimalParkingDuration; - this.minimalNoDataDuration = minimalNoDataDuration; - this.useIgnition = useIgnition; - this.processInvalidPositions = processInvalidPositions; - this.speedThreshold = speedThreshold; - } - - private final double minimalTripDistance; - - public double getMinimalTripDistance() { - return minimalTripDistance; - } - - private final long minimalTripDuration; - - public long getMinimalTripDuration() { - return minimalTripDuration; - } - - private final long minimalParkingDuration; - - public long getMinimalParkingDuration() { - return minimalParkingDuration; - } - - private final long minimalNoDataDuration; - - public long getMinimalNoDataDuration() { - return minimalNoDataDuration; - } - - private final boolean useIgnition; - - public boolean getUseIgnition() { - return useIgnition; - } - - private final boolean processInvalidPositions; - - public boolean getProcessInvalidPositions() { - return processInvalidPositions; - } - - private final double speedThreshold; - - public double getSpeedThreshold() { - return speedThreshold; - } - -} diff --git a/src/test/java/org/traccar/handler/MotionHandlerTest.java b/src/test/java/org/traccar/handler/MotionHandlerTest.java index aa73ac60a..93fd16206 100644 --- a/src/test/java/org/traccar/handler/MotionHandlerTest.java +++ b/src/test/java/org/traccar/handler/MotionHandlerTest.java @@ -2,7 +2,7 @@ package org.traccar.handler; import org.junit.Test; import org.traccar.model.Position; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 94dab4049..780d1b833 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -4,7 +4,7 @@ import org.junit.Test; import org.traccar.BaseTest; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import org.traccar.session.DeviceState; import java.text.DateFormat; diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index be473a341..247e43499 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -5,9 +5,10 @@ import org.traccar.BaseTest; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.StopReport; import org.traccar.reports.model.TripReport; -import org.traccar.reports.model.TripsConfig; +import org.traccar.reports.common.TripsConfig; import java.text.DateFormat; import java.text.ParseException; -- cgit v1.2.3 From 94a2a94330d82fa1c1960b8783e5061c188196e3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 10:55:50 -0700 Subject: Rename report models --- .../org/traccar/api/resource/ReportResource.java | 12 +- src/main/java/org/traccar/reports/Events.java | 6 +- src/main/java/org/traccar/reports/Route.java | 6 +- src/main/java/org/traccar/reports/Stops.java | 18 +-- src/main/java/org/traccar/reports/Summary.java | 22 ++-- src/main/java/org/traccar/reports/Trips.java | 20 ++-- .../org/traccar/reports/common/ReportUtils.java | 22 ++-- .../java/org/traccar/reports/model/BaseReport.java | 126 -------------------- .../org/traccar/reports/model/BaseReportItem.java | 126 ++++++++++++++++++++ .../org/traccar/reports/model/DeviceReport.java | 55 --------- .../traccar/reports/model/DeviceReportSection.java | 55 +++++++++ .../java/org/traccar/reports/model/StopReport.java | 80 ------------- .../org/traccar/reports/model/StopReportItem.java | 80 +++++++++++++ .../org/traccar/reports/model/SummaryReport.java | 30 ----- .../traccar/reports/model/SummaryReportItem.java | 30 +++++ .../java/org/traccar/reports/model/TripReport.java | 130 --------------------- .../org/traccar/reports/model/TripReportItem.java | 130 +++++++++++++++++++++ .../java/org/traccar/reports/ReportUtilsTest.java | 82 ++++++------- 18 files changed, 515 insertions(+), 515 deletions(-) delete mode 100644 src/main/java/org/traccar/reports/model/BaseReport.java create mode 100644 src/main/java/org/traccar/reports/model/BaseReportItem.java delete mode 100644 src/main/java/org/traccar/reports/model/DeviceReport.java create mode 100644 src/main/java/org/traccar/reports/model/DeviceReportSection.java delete mode 100644 src/main/java/org/traccar/reports/model/StopReport.java create mode 100644 src/main/java/org/traccar/reports/model/StopReportItem.java delete mode 100644 src/main/java/org/traccar/reports/model/SummaryReport.java create mode 100644 src/main/java/org/traccar/reports/model/SummaryReportItem.java delete mode 100644 src/main/java/org/traccar/reports/model/TripReport.java create mode 100644 src/main/java/org/traccar/reports/model/TripReportItem.java diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index a7bbe1067..5346df31b 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -46,9 +46,9 @@ import org.traccar.model.UserRestrictions; import org.traccar.reports.Events; import org.traccar.reports.Summary; import org.traccar.reports.Trips; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.SummaryReport; -import org.traccar.reports.model.TripReport; +import org.traccar.reports.model.StopReportItem; +import org.traccar.reports.model.SummaryReportItem; +import org.traccar.reports.model.TripReportItem; import org.traccar.reports.Route; import org.traccar.reports.Stops; import org.traccar.storage.StorageException; @@ -147,7 +147,7 @@ public class ReportResource extends BaseResource { @Path("summary") @GET - public Collection getSummary( + public Collection getSummary( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily) throws StorageException { @@ -174,7 +174,7 @@ public class ReportResource extends BaseResource { @Path("trips") @GET @Produces(MediaType.APPLICATION_JSON) - public Collection getTrips( + public Collection getTrips( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); @@ -199,7 +199,7 @@ public class ReportResource extends BaseResource { @Path("stops") @GET @Produces(MediaType.APPLICATION_JSON) - public Collection getStops( + public Collection getStops( @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); diff --git a/src/main/java/org/traccar/reports/Events.java b/src/main/java/org/traccar/reports/Events.java index c5db305ed..130fba724 100644 --- a/src/main/java/org/traccar/reports/Events.java +++ b/src/main/java/org/traccar/reports/Events.java @@ -34,7 +34,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReport; +import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -73,7 +73,7 @@ public final class Events { Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesEvents = new ArrayList<>(); + ArrayList devicesEvents = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); @@ -107,7 +107,7 @@ public final class Events { iterator.remove(); } } - DeviceReport deviceEvents = new DeviceReport(); + DeviceReportSection deviceEvents = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/Route.java b/src/main/java/org/traccar/reports/Route.java index d7745157a..5b8629aad 100644 --- a/src/main/java/org/traccar/reports/Route.java +++ b/src/main/java/org/traccar/reports/Route.java @@ -30,7 +30,7 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReport; +import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.StorageException; public final class Route { @@ -53,13 +53,13 @@ public final class Route { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesRoutes = new ArrayList<>(); + ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection positions = Context.getDataManager() .getPositions(deviceId, from, to); - DeviceReport deviceRoutes = new DeviceReport(); + DeviceReportSection deviceRoutes = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/Stops.java b/src/main/java/org/traccar/reports/Stops.java index 82eb62f66..e688d53da 100644 --- a/src/main/java/org/traccar/reports/Stops.java +++ b/src/main/java/org/traccar/reports/Stops.java @@ -33,8 +33,8 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReport; -import org.traccar.reports.model.StopReport; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.reports.model.StopReportItem; import org.traccar.storage.StorageException; public final class Stops { @@ -42,7 +42,7 @@ public final class Stops { private Stops() { } - private static Collection detectStops(long deviceId, Date from, Date to) throws StorageException { + private static Collection detectStops(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); @@ -51,14 +51,14 @@ public final class Stops { return ReportUtils.detectTripsAndStops( identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, StopReport.class); + Context.getTripsConfig(), ignoreOdometer, StopReportItem.class); } - public static Collection getObjects( + public static Collection getObjects( long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); + ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectStops(deviceId, from, to)); @@ -70,12 +70,12 @@ public final class Stops { OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesStops = new ArrayList<>(); + ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection stops = detectStops(deviceId, from, to); - DeviceReport deviceStops = new DeviceReport(); + Collection stops = detectStops(deviceId, from, to); + DeviceReportSection deviceStops = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java index 20d80a9f5..30c4cb057 100644 --- a/src/main/java/org/traccar/reports/Summary.java +++ b/src/main/java/org/traccar/reports/Summary.java @@ -30,7 +30,7 @@ import org.traccar.Context; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.SummaryReport; +import org.traccar.reports.model.SummaryReportItem; import org.traccar.storage.StorageException; public final class Summary { @@ -38,8 +38,8 @@ public final class Summary { private Summary() { } - private static SummaryReport calculateSummaryResult(long deviceId, Collection positions) { - SummaryReport result = new SummaryReport(); + private static SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { + SummaryReportItem result = new SummaryReportItem(); result.setDeviceId(deviceId); result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); if (positions != null && !positions.isEmpty()) { @@ -97,12 +97,12 @@ public final class Summary { return calendar.get(Calendar.DAY_OF_MONTH); } - private static Collection calculateSummaryResults( + private static Collection calculateSummaryResults( long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { ArrayList positions = new ArrayList<>(Context.getDataManager().getPositions(deviceId, from, to)); - ArrayList results = new ArrayList<>(); + ArrayList results = new ArrayList<>(); if (daily && !positions.isEmpty()) { int startIndex = 0; int startDay = getDay(userId, positions.iterator().next().getFixTime()); @@ -122,14 +122,14 @@ public final class Summary { return results; } - public static Collection getObjects(long userId, Collection deviceIds, - Collection groupIds, Date from, Date to, boolean daily) throws StorageException { + public static Collection getObjects(long userId, Collection deviceIds, + Collection groupIds, Date from, Date to, boolean daily) throws StorageException { ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); + ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); - for (SummaryReport summaryReport : deviceResults) { + Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); + for (SummaryReportItem summaryReport : deviceResults) { if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { result.add(summaryReport); } @@ -142,7 +142,7 @@ public final class Summary { long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); - Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); + Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { diff --git a/src/main/java/org/traccar/reports/Trips.java b/src/main/java/org/traccar/reports/Trips.java index 58131debb..74e24cf2f 100644 --- a/src/main/java/org/traccar/reports/Trips.java +++ b/src/main/java/org/traccar/reports/Trips.java @@ -32,8 +32,8 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReport; -import org.traccar.reports.model.TripReport; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.reports.model.TripReportItem; import org.traccar.storage.StorageException; public final class Trips { @@ -41,7 +41,7 @@ public final class Trips { private Trips() { } - private static Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { + private static Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); @@ -50,13 +50,13 @@ public final class Trips { return ReportUtils.detectTripsAndStops( identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, TripReport.class); + Context.getTripsConfig(), ignoreOdometer, TripReportItem.class); } - public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException { + public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); + ArrayList result = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectTrips(deviceId, from, to)); @@ -68,12 +68,12 @@ public final class Trips { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesTrips = new ArrayList<>(); + ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection trips = detectTrips(deviceId, from, to); - DeviceReport deviceTrips = new DeviceReport(); + Collection trips = detectTrips(deviceId, from, to); + DeviceReportSection deviceTrips = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 27972b453..b56b58a58 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -37,9 +37,9 @@ import org.traccar.session.DeviceState; import org.traccar.model.Driver; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.reports.model.BaseReport; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.TripReport; +import org.traccar.reports.model.BaseReportItem; +import org.traccar.reports.model.StopReportItem; +import org.traccar.reports.model.TripReportItem; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -185,7 +185,7 @@ public final class ReportUtils { transformer.write(); } - private static TripReport calculateTrip( + private static TripReportItem calculateTrip( IdentityManager identityManager, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { @@ -200,7 +200,7 @@ public final class ReportUtils { } } - TripReport trip = new TripReport(); + TripReportItem trip = new TripReportItem(); long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); @@ -253,14 +253,14 @@ public final class ReportUtils { return trip; } - private static StopReport calculateStop( + private static StopReportItem calculateStop( IdentityManager identityManager, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); - StopReport stop = new StopReport(); + StopReportItem stop = new StopReportItem(); long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); @@ -302,11 +302,11 @@ public final class ReportUtils { } - private static T calculateTripOrStop( + private static T calculateTripOrStop( IdentityManager identityManager, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { - if (reportClass.equals(TripReport.class)) { + if (reportClass.equals(TripReportItem.class)) { return (T) calculateTrip(identityManager, positions, startIndex, endIndex, ignoreOdometer); } else { return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); @@ -333,7 +333,7 @@ public final class ReportUtils { } } - public static Collection detectTripsAndStops( + public static Collection detectTripsAndStops( IdentityManager identityManager, DeviceManager deviceManager, Collection positionCollection, TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) { @@ -342,7 +342,7 @@ public final class ReportUtils { ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { - boolean trips = reportClass.equals(TripReport.class); + boolean trips = reportClass.equals(TripReportItem.class); MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); diff --git a/src/main/java/org/traccar/reports/model/BaseReport.java b/src/main/java/org/traccar/reports/model/BaseReport.java deleted file mode 100644 index 928c0557d..000000000 --- a/src/main/java/org/traccar/reports/model/BaseReport.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@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.reports.model; - -import java.util.Date; - -public class BaseReport { - - private long deviceId; - - public long getDeviceId() { - return deviceId; - } - - public void setDeviceId(long deviceId) { - this.deviceId = deviceId; - } - - private String deviceName; - - public String getDeviceName() { - return deviceName; - } - - public void setDeviceName(String deviceName) { - this.deviceName = deviceName; - } - - private double distance; - - public double getDistance() { - return distance; - } - - public void setDistance(double distance) { - this.distance = distance; - } - - public void addDistance(double distance) { - this.distance += distance; - } - - private double averageSpeed; - - public double getAverageSpeed() { - return averageSpeed; - } - - public void setAverageSpeed(double averageSpeed) { - this.averageSpeed = averageSpeed; - } - - private double maxSpeed; - - public double getMaxSpeed() { - return maxSpeed; - } - - public void setMaxSpeed(double maxSpeed) { - this.maxSpeed = maxSpeed; - } - - private double spentFuel; - - public double getSpentFuel() { - return spentFuel; - } - - public void setSpentFuel(double spentFuel) { - this.spentFuel = spentFuel; - } - - private double startOdometer; - - public double getStartOdometer() { - return startOdometer; - } - - public void setStartOdometer(double startOdometer) { - this.startOdometer = startOdometer; - } - private double endOdometer; - - public double getEndOdometer() { - return endOdometer; - } - - public void setEndOdometer(double endOdometer) { - this.endOdometer = endOdometer; - } - - private Date startTime; - - public Date getStartTime() { - return startTime; - } - - public void setStartTime(Date startTime) { - this.startTime = startTime; - } - - private Date endTime; - - public Date getEndTime() { - return endTime; - } - - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - -} diff --git a/src/main/java/org/traccar/reports/model/BaseReportItem.java b/src/main/java/org/traccar/reports/model/BaseReportItem.java new file mode 100644 index 000000000..6e270dfe3 --- /dev/null +++ b/src/main/java/org/traccar/reports/model/BaseReportItem.java @@ -0,0 +1,126 @@ +/* + * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Andrey Kunitsyn (andrey@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.reports.model; + +import java.util.Date; + +public class BaseReportItem { + + private long deviceId; + + public long getDeviceId() { + return deviceId; + } + + public void setDeviceId(long deviceId) { + this.deviceId = deviceId; + } + + private String deviceName; + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + private double distance; + + public double getDistance() { + return distance; + } + + public void setDistance(double distance) { + this.distance = distance; + } + + public void addDistance(double distance) { + this.distance += distance; + } + + private double averageSpeed; + + public double getAverageSpeed() { + return averageSpeed; + } + + public void setAverageSpeed(double averageSpeed) { + this.averageSpeed = averageSpeed; + } + + private double maxSpeed; + + public double getMaxSpeed() { + return maxSpeed; + } + + public void setMaxSpeed(double maxSpeed) { + this.maxSpeed = maxSpeed; + } + + private double spentFuel; + + public double getSpentFuel() { + return spentFuel; + } + + public void setSpentFuel(double spentFuel) { + this.spentFuel = spentFuel; + } + + private double startOdometer; + + public double getStartOdometer() { + return startOdometer; + } + + public void setStartOdometer(double startOdometer) { + this.startOdometer = startOdometer; + } + private double endOdometer; + + public double getEndOdometer() { + return endOdometer; + } + + public void setEndOdometer(double endOdometer) { + this.endOdometer = endOdometer; + } + + private Date startTime; + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + private Date endTime; + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + +} diff --git a/src/main/java/org/traccar/reports/model/DeviceReport.java b/src/main/java/org/traccar/reports/model/DeviceReport.java deleted file mode 100644 index 932753d15..000000000 --- a/src/main/java/org/traccar/reports/model/DeviceReport.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@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.reports.model; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class DeviceReport { - - private String deviceName; - - public String getDeviceName() { - return deviceName; - } - - public void setDeviceName(String deviceName) { - this.deviceName = deviceName; - } - - private String groupName = ""; - - public String getGroupName() { - return groupName; - } - - public void setGroupName(String groupName) { - this.groupName = groupName; - } - - private List objects; - - public Collection getObjects() { - return objects; - } - - public void setObjects(Collection objects) { - this.objects = new ArrayList<>(objects); - } - -} diff --git a/src/main/java/org/traccar/reports/model/DeviceReportSection.java b/src/main/java/org/traccar/reports/model/DeviceReportSection.java new file mode 100644 index 000000000..ffc4d774f --- /dev/null +++ b/src/main/java/org/traccar/reports/model/DeviceReportSection.java @@ -0,0 +1,55 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Andrey Kunitsyn (andrey@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.reports.model; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class DeviceReportSection { + + private String deviceName; + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + private String groupName = ""; + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + private List objects; + + public Collection getObjects() { + return objects; + } + + public void setObjects(Collection objects) { + this.objects = new ArrayList<>(objects); + } + +} diff --git a/src/main/java/org/traccar/reports/model/StopReport.java b/src/main/java/org/traccar/reports/model/StopReport.java deleted file mode 100644 index e20f2c503..000000000 --- a/src/main/java/org/traccar/reports/model/StopReport.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.reports.model; - -public class StopReport extends BaseReport { - - private long positionId; - - public long getPositionId() { - return positionId; - } - - public void setPositionId(long positionId) { - this.positionId = positionId; - } - - private double latitude; - - public double getLatitude() { - return latitude; - } - - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - private double longitude; - - public double getLongitude() { - return longitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - private String address; - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - private long duration; - - public long getDuration() { - return duration; - } - - public void setDuration(long duration) { - this.duration = duration; - } - - private long engineHours; // milliseconds - - public long getEngineHours() { - return engineHours; - } - - public void setEngineHours(long engineHours) { - this.engineHours = engineHours; - } -} diff --git a/src/main/java/org/traccar/reports/model/StopReportItem.java b/src/main/java/org/traccar/reports/model/StopReportItem.java new file mode 100644 index 000000000..3c35bdc21 --- /dev/null +++ b/src/main/java/org/traccar/reports/model/StopReportItem.java @@ -0,0 +1,80 @@ +/* + * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@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.reports.model; + +public class StopReportItem extends BaseReportItem { + + private long positionId; + + public long getPositionId() { + return positionId; + } + + public void setPositionId(long positionId) { + this.positionId = positionId; + } + + private double latitude; + + public double getLatitude() { + return latitude; + } + + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + private double longitude; + + public double getLongitude() { + return longitude; + } + + public void setLongitude(double longitude) { + this.longitude = longitude; + } + + private String address; + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + private long duration; + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + private long engineHours; // milliseconds + + public long getEngineHours() { + return engineHours; + } + + public void setEngineHours(long engineHours) { + this.engineHours = engineHours; + } +} diff --git a/src/main/java/org/traccar/reports/model/SummaryReport.java b/src/main/java/org/traccar/reports/model/SummaryReport.java deleted file mode 100644 index 886f8b9e2..000000000 --- a/src/main/java/org/traccar/reports/model/SummaryReport.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@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.reports.model; - -public class SummaryReport extends BaseReport { - - private long engineHours; // milliseconds - - public long getEngineHours() { - return engineHours; - } - - public void setEngineHours(long engineHours) { - this.engineHours = engineHours; - } -} diff --git a/src/main/java/org/traccar/reports/model/SummaryReportItem.java b/src/main/java/org/traccar/reports/model/SummaryReportItem.java new file mode 100644 index 000000000..44a15cf1d --- /dev/null +++ b/src/main/java/org/traccar/reports/model/SummaryReportItem.java @@ -0,0 +1,30 @@ +/* + * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@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.reports.model; + +public class SummaryReportItem extends BaseReportItem { + + private long engineHours; // milliseconds + + public long getEngineHours() { + return engineHours; + } + + public void setEngineHours(long engineHours) { + this.engineHours = engineHours; + } +} diff --git a/src/main/java/org/traccar/reports/model/TripReport.java b/src/main/java/org/traccar/reports/model/TripReport.java deleted file mode 100644 index 151c34bd5..000000000 --- a/src/main/java/org/traccar/reports/model/TripReport.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@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.reports.model; - -public class TripReport extends BaseReport { - - private long startPositionId; - - public long getStartPositionId() { - return startPositionId; - } - - public void setStartPositionId(long startPositionId) { - this.startPositionId = startPositionId; - } - - private long endPositionId; - - public long getEndPositionId() { - return endPositionId; - } - - public void setEndPositionId(long endPositionId) { - this.endPositionId = endPositionId; - } - - private double startLat; - - public double getStartLat() { - return startLat; - } - - public void setStartLat(double startLat) { - this.startLat = startLat; - } - - private double startLon; - - public double getStartLon() { - return startLon; - } - - public void setStartLon(double startLon) { - this.startLon = startLon; - } - - private double endLat; - - public double getEndLat() { - return endLat; - } - - public void setEndLat(double endLat) { - this.endLat = endLat; - } - - private double endLon; - - public double getEndLon() { - return endLon; - } - - public void setEndLon(double endLon) { - this.endLon = endLon; - } - - private String startAddress; - - public String getStartAddress() { - return startAddress; - } - - public void setStartAddress(String address) { - this.startAddress = address; - } - - private String endAddress; - - public String getEndAddress() { - return endAddress; - } - - public void setEndAddress(String address) { - this.endAddress = address; - } - - private long duration; - - public long getDuration() { - return duration; - } - - public void setDuration(long duration) { - this.duration = duration; - } - - private String driverUniqueId; - - public String getDriverUniqueId() { - return driverUniqueId; - } - - public void setDriverUniqueId(String driverUniqueId) { - this.driverUniqueId = driverUniqueId; - } - - private String driverName; - - public String getDriverName() { - return driverName; - } - - public void setDriverName(String driverName) { - this.driverName = driverName; - } -} diff --git a/src/main/java/org/traccar/reports/model/TripReportItem.java b/src/main/java/org/traccar/reports/model/TripReportItem.java new file mode 100644 index 000000000..332a34cca --- /dev/null +++ b/src/main/java/org/traccar/reports/model/TripReportItem.java @@ -0,0 +1,130 @@ +/* + * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Andrey Kunitsyn (andrey@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.reports.model; + +public class TripReportItem extends BaseReportItem { + + private long startPositionId; + + public long getStartPositionId() { + return startPositionId; + } + + public void setStartPositionId(long startPositionId) { + this.startPositionId = startPositionId; + } + + private long endPositionId; + + public long getEndPositionId() { + return endPositionId; + } + + public void setEndPositionId(long endPositionId) { + this.endPositionId = endPositionId; + } + + private double startLat; + + public double getStartLat() { + return startLat; + } + + public void setStartLat(double startLat) { + this.startLat = startLat; + } + + private double startLon; + + public double getStartLon() { + return startLon; + } + + public void setStartLon(double startLon) { + this.startLon = startLon; + } + + private double endLat; + + public double getEndLat() { + return endLat; + } + + public void setEndLat(double endLat) { + this.endLat = endLat; + } + + private double endLon; + + public double getEndLon() { + return endLon; + } + + public void setEndLon(double endLon) { + this.endLon = endLon; + } + + private String startAddress; + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String address) { + this.startAddress = address; + } + + private String endAddress; + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String address) { + this.endAddress = address; + } + + private long duration; + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + private String driverUniqueId; + + public String getDriverUniqueId() { + return driverUniqueId; + } + + public void setDriverUniqueId(String driverUniqueId) { + this.driverUniqueId = driverUniqueId; + } + + private String driverName; + + public String getDriverName() { + return driverName; + } + + public void setDriverName(String driverName) { + this.driverName = driverName; + } +} diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 247e43499..e947a9afa 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -6,8 +6,8 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.StopReport; -import org.traccar.reports.model.TripReport; +import org.traccar.reports.model.StopReportItem; +import org.traccar.reports.model.TripReportItem; import org.traccar.reports.common.TripsConfig; import java.text.DateFormat; @@ -93,13 +93,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); - TripReport itemTrip = trips.iterator().next(); + TripReportItem itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemTrip.getEndTime()); @@ -108,15 +108,15 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); - Iterator iterator = stops.iterator(); + Iterator iterator = stops.iterator(); - StopReport itemStop = iterator.next(); + StopReportItem itemStop = iterator.next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getEndTime()); @@ -147,13 +147,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); - TripReport itemTrip = trips.iterator().next(); + TripReportItem itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemTrip.getEndTime()); @@ -163,7 +163,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); + mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -177,15 +177,15 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); - Iterator iterator = stops.iterator(); + Iterator iterator = stops.iterator(); - StopReport itemStop = iterator.next(); + StopReportItem itemStop = iterator.next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getEndTime()); @@ -218,13 +218,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); - TripReport itemTrip = trips.iterator().next(); + TripReportItem itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:09:00.000"), itemTrip.getEndTime()); @@ -233,15 +233,15 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); - Iterator iterator = stops.iterator(); + Iterator iterator = stops.iterator(); - StopReport itemStop = iterator.next(); + StopReportItem itemStop = iterator.next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getEndTime()); @@ -268,13 +268,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = result.iterator().next(); + StopReportItem itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); @@ -295,13 +295,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = result.iterator().next(); + StopReportItem itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:04:00.000"), itemStop.getEndTime()); @@ -322,13 +322,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); - StopReport itemStop = result.iterator().next(); + StopReportItem itemStop = result.iterator().next(); assertEquals(date("2016-01-01 00:02:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:05:00.000"), itemStop.getEndTime()); @@ -349,8 +349,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); - Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection result = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -372,13 +372,13 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); - Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReport.class); + Collection trips = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); - TripReport itemTrip = trips.iterator().next(); + TripReportItem itemTrip = trips.iterator().next(); assertEquals(date("2016-01-01 00:00:00.000"), itemTrip.getStartTime()); assertEquals(date("2016-01-01 00:04:00.000"), itemTrip.getEndTime()); @@ -387,13 +387,13 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReport.class); + Collection stops = ReportUtils.detectTripsAndStops( + mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); - StopReport itemStop = stops.iterator().next(); + StopReportItem itemStop = stops.iterator().next(); assertEquals(date("2016-01-01 00:04:00.000"), itemStop.getStartTime()); assertEquals(date("2016-01-01 00:24:00.000"), itemStop.getEndTime()); -- cgit v1.2.3 From 31c4ad41f4d91dec3c98af06614e9518d3689a14 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 11:01:01 -0700 Subject: Inject report providers --- .../org/traccar/api/resource/ReportResource.java | 46 ++++-- src/main/java/org/traccar/reports/Events.java | 136 ------------------ .../org/traccar/reports/EventsReportProvider.java | 133 +++++++++++++++++ src/main/java/org/traccar/reports/Route.java | 86 ----------- .../org/traccar/reports/RouteReportProvider.java | 83 +++++++++++ src/main/java/org/traccar/reports/Stops.java | 103 -------------- .../org/traccar/reports/StopsReportProvider.java | 100 +++++++++++++ src/main/java/org/traccar/reports/Summary.java | 157 --------------------- .../org/traccar/reports/SummaryReportProvider.java | 155 ++++++++++++++++++++ src/main/java/org/traccar/reports/Trips.java | 101 ------------- .../org/traccar/reports/TripsReportProvider.java | 98 +++++++++++++ 11 files changed, 600 insertions(+), 598 deletions(-) delete mode 100644 src/main/java/org/traccar/reports/Events.java create mode 100644 src/main/java/org/traccar/reports/EventsReportProvider.java delete mode 100644 src/main/java/org/traccar/reports/Route.java create mode 100644 src/main/java/org/traccar/reports/RouteReportProvider.java delete mode 100644 src/main/java/org/traccar/reports/Stops.java create mode 100644 src/main/java/org/traccar/reports/StopsReportProvider.java delete mode 100644 src/main/java/org/traccar/reports/Summary.java create mode 100644 src/main/java/org/traccar/reports/SummaryReportProvider.java delete mode 100644 src/main/java/org/traccar/reports/Trips.java create mode 100644 src/main/java/org/traccar/reports/TripsReportProvider.java diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 5346df31b..38eb52685 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -23,6 +23,7 @@ import java.util.Date; import java.util.List; import javax.activation.DataHandler; +import javax.inject.Inject; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import javax.mail.util.ByteArrayDataSource; @@ -43,14 +44,14 @@ import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.UserRestrictions; -import org.traccar.reports.Events; -import org.traccar.reports.Summary; -import org.traccar.reports.Trips; +import org.traccar.reports.EventsReportProvider; +import org.traccar.reports.SummaryReportProvider; +import org.traccar.reports.TripsReportProvider; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.SummaryReportItem; import org.traccar.reports.model.TripReportItem; -import org.traccar.reports.Route; -import org.traccar.reports.Stops; +import org.traccar.reports.RouteReportProvider; +import org.traccar.reports.StopsReportProvider; import org.traccar.storage.StorageException; @Path("reports") @@ -63,6 +64,21 @@ public class ReportResource extends BaseResource { private static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; private static final String CONTENT_DISPOSITION_VALUE_XLSX = "attachment; filename=report.xlsx"; + @Inject + private EventsReportProvider eventsReportProvider; + + @Inject + private RouteReportProvider routeReportProvider; + + @Inject + private StopsReportProvider stopsReportProvider; + + @Inject + private SummaryReportProvider summaryReportProvider; + + @Inject + private TripsReportProvider tripsReportProvider; + private interface ReportExecutor { void execute(ByteArrayOutputStream stream) throws StorageException, IOException; } @@ -102,7 +118,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); - return Route.getObjects(getUserId(), deviceIds, groupIds, from, to); + return routeReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); } @Path("route") @@ -115,7 +131,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); - Route.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); + routeReportProvider.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); }); } @@ -127,7 +143,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - return Events.getObjects(storage, getUserId(), deviceIds, groupIds, types, from, to); + return eventsReportProvider.getObjects(storage, getUserId(), deviceIds, groupIds, types, from, to); } @Path("events") @@ -141,7 +157,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - Events.getExcel(stream, storage, getUserId(), deviceIds, groupIds, types, from, to); + eventsReportProvider.getExcel(stream, storage, getUserId(), deviceIds, groupIds, types, from, to); }); } @@ -153,7 +169,7 @@ public class ReportResource extends BaseResource { throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); - return Summary.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); + return summaryReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); } @Path("summary") @@ -167,7 +183,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); - Summary.getExcel(stream, getUserId(), deviceIds, groupIds, from, to, daily); + summaryReportProvider.getExcel(stream, getUserId(), deviceIds, groupIds, from, to, daily); }); } @@ -179,7 +195,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); - return Trips.getObjects(getUserId(), deviceIds, groupIds, from, to); + return tripsReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); } @Path("trips") @@ -192,7 +208,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); - Trips.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); + tripsReportProvider.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); }); } @@ -204,7 +220,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); - return Stops.getObjects(getUserId(), deviceIds, groupIds, from, to); + return stopsReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); } @Path("stops") @@ -217,7 +233,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); - Stops.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); + stopsReportProvider.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); }); } diff --git a/src/main/java/org/traccar/reports/Events.java b/src/main/java/org/traccar/reports/Events.java deleted file mode 100644 index 130fba724..000000000 --- a/src/main/java/org/traccar/reports/Events.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) - * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Geofence; -import org.traccar.model.Group; -import org.traccar.model.Maintenance; -import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReportSection; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; - -public final class Events { - - private Events() { - } - - public static Collection getObjects( - Storage storage, long userId, - Collection deviceIds, Collection groupIds, - Collection types, Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection events = Context.getDataManager().getEvents(deviceId, from, to); - boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); - for (Event event : events) { - if (all || types.contains(event.getType())) { - long geofenceId = event.getGeofenceId(); - long maintenanceId = event.getMaintenanceId(); - if ((geofenceId == 0 || ReportUtils.getObject(storage, userId, Geofence.class, geofenceId) != null) - && (maintenanceId == 0 - || ReportUtils.getObject(storage, userId, Maintenance.class, maintenanceId) != null)) { - result.add(event); - } - } - } - } - return result; - } - - public static void getExcel( - OutputStream outputStream, Storage storage, long userId, - Collection deviceIds, Collection groupIds, - Collection types, Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesEvents = new ArrayList<>(); - ArrayList sheetNames = new ArrayList<>(); - HashMap geofenceNames = new HashMap<>(); - HashMap maintenanceNames = new HashMap<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection events = Context.getDataManager().getEvents(deviceId, from, to); - boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); - for (Iterator iterator = events.iterator(); iterator.hasNext();) { - Event event = iterator.next(); - if (all || types.contains(event.getType())) { - long geofenceId = event.getGeofenceId(); - long maintenanceId = event.getMaintenanceId(); - if (geofenceId != 0) { - Geofence geofence = ReportUtils.getObject( - storage, userId, Geofence.class, geofenceId); - if (geofence != null) { - geofenceNames.put(geofenceId, geofence.getName()); - } else { - iterator.remove(); - } - } else if (maintenanceId != 0) { - Maintenance maintenance = ReportUtils.getObject( - storage, userId, Maintenance.class, maintenanceId); - if (maintenance != null) { - maintenanceNames.put(maintenanceId, maintenance.getName()); - } else { - iterator.remove(); - } - } - } else { - iterator.remove(); - } - } - DeviceReportSection deviceEvents = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceEvents.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceEvents.setGroupName(group.getName()); - } - } - deviceEvents.setObjects(events); - devicesEvents.add(deviceEvents); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesEvents); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("geofenceNames", geofenceNames); - jxlsContext.putVar("maintenanceNames", maintenanceNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } -} diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java new file mode 100644 index 000000000..c4b0aad86 --- /dev/null +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -0,0 +1,133 @@ +/* + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@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.reports; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; + +import org.apache.poi.ss.util.WorkbookUtil; +import org.traccar.Context; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Geofence; +import org.traccar.model.Group; +import org.traccar.model.Maintenance; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; + +public class EventsReportProvider { + + public Collection getObjects( + Storage storage, long userId, + Collection deviceIds, Collection groupIds, + Collection types, Date from, Date to) throws StorageException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList result = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection events = Context.getDataManager().getEvents(deviceId, from, to); + boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); + for (Event event : events) { + if (all || types.contains(event.getType())) { + long geofenceId = event.getGeofenceId(); + long maintenanceId = event.getMaintenanceId(); + if ((geofenceId == 0 || ReportUtils.getObject(storage, userId, Geofence.class, geofenceId) != null) + && (maintenanceId == 0 + || ReportUtils.getObject(storage, userId, Maintenance.class, maintenanceId) != null)) { + result.add(event); + } + } + } + } + return result; + } + + public void getExcel( + OutputStream outputStream, Storage storage, long userId, + Collection deviceIds, Collection groupIds, + Collection types, Date from, Date to) throws StorageException, IOException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList devicesEvents = new ArrayList<>(); + ArrayList sheetNames = new ArrayList<>(); + HashMap geofenceNames = new HashMap<>(); + HashMap maintenanceNames = new HashMap<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection events = Context.getDataManager().getEvents(deviceId, from, to); + boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); + for (Iterator iterator = events.iterator(); iterator.hasNext();) { + Event event = iterator.next(); + if (all || types.contains(event.getType())) { + long geofenceId = event.getGeofenceId(); + long maintenanceId = event.getMaintenanceId(); + if (geofenceId != 0) { + Geofence geofence = ReportUtils.getObject( + storage, userId, Geofence.class, geofenceId); + if (geofence != null) { + geofenceNames.put(geofenceId, geofence.getName()); + } else { + iterator.remove(); + } + } else if (maintenanceId != 0) { + Maintenance maintenance = ReportUtils.getObject( + storage, userId, Maintenance.class, maintenanceId); + if (maintenance != null) { + maintenanceNames.put(maintenanceId, maintenance.getName()); + } else { + iterator.remove(); + } + } + } else { + iterator.remove(); + } + } + DeviceReportSection deviceEvents = new DeviceReportSection(); + Device device = Context.getIdentityManager().getById(deviceId); + deviceEvents.setDeviceName(device.getName()); + sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); + if (device.getGroupId() != 0) { + Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (group != null) { + deviceEvents.setGroupName(group.getName()); + } + } + deviceEvents.setObjects(events); + devicesEvents.add(deviceEvents); + } + String templatePath = Context.getConfig().getString("report.templatesPath", + "templates/export/"); + try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { + org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + jxlsContext.putVar("devices", devicesEvents); + jxlsContext.putVar("sheetNames", sheetNames); + jxlsContext.putVar("geofenceNames", geofenceNames); + jxlsContext.putVar("maintenanceNames", maintenanceNames); + jxlsContext.putVar("from", from); + jxlsContext.putVar("to", to); + ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + } + } +} diff --git a/src/main/java/org/traccar/reports/Route.java b/src/main/java/org/traccar/reports/Route.java deleted file mode 100644 index 5b8629aad..000000000 --- a/src/main/java/org/traccar/reports/Route.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.model.Position; -import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReportSection; -import org.traccar.storage.StorageException; - -public final class Route { - - private Route() { - } - - public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(Context.getDataManager().getPositions(deviceId, from, to)); - } - return result; - } - - public static void getExcel(OutputStream outputStream, - long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesRoutes = new ArrayList<>(); - ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection positions = Context.getDataManager() - .getPositions(deviceId, from, to); - DeviceReportSection deviceRoutes = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceRoutes.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceRoutes.setGroupName(group.getName()); - } - } - deviceRoutes.setObjects(positions); - devicesRoutes.add(deviceRoutes); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesRoutes); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } -} diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java new file mode 100644 index 000000000..4c4a41405 --- /dev/null +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -0,0 +1,83 @@ +/* + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Andrey Kunitsyn (andrey@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.reports; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; + +import org.apache.poi.ss.util.WorkbookUtil; +import org.traccar.Context; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.model.Position; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.storage.StorageException; + +public class RouteReportProvider { + + public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList result = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + result.addAll(Context.getDataManager().getPositions(deviceId, from, to)); + } + return result; + } + + public void getExcel(OutputStream outputStream, + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException, IOException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList devicesRoutes = new ArrayList<>(); + ArrayList sheetNames = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection positions = Context.getDataManager() + .getPositions(deviceId, from, to); + DeviceReportSection deviceRoutes = new DeviceReportSection(); + Device device = Context.getIdentityManager().getById(deviceId); + deviceRoutes.setDeviceName(device.getName()); + sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); + if (device.getGroupId() != 0) { + Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (group != null) { + deviceRoutes.setGroupName(group.getName()); + } + } + deviceRoutes.setObjects(positions); + devicesRoutes.add(deviceRoutes); + } + String templatePath = Context.getConfig().getString("report.templatesPath", + "templates/export/"); + try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { + org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + jxlsContext.putVar("devices", devicesRoutes); + jxlsContext.putVar("sheetNames", sheetNames); + jxlsContext.putVar("from", from); + jxlsContext.putVar("to", to); + ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + } + } +} diff --git a/src/main/java/org/traccar/reports/Stops.java b/src/main/java/org/traccar/reports/Stops.java deleted file mode 100644 index e688d53da..000000000 --- a/src/main/java/org/traccar/reports/Stops.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReportSection; -import org.traccar.reports.model.StopReportItem; -import org.traccar.storage.StorageException; - -public final class Stops { - - private Stops() { - } - - private static Collection detectStops(long deviceId, Date from, Date to) throws StorageException { - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - - IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); - DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - - return ReportUtils.detectTripsAndStops( - identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, StopReportItem.class); - } - - public static Collection getObjects( - long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(detectStops(deviceId, from, to)); - } - return result; - } - - public static void getExcel( - OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesStops = new ArrayList<>(); - ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection stops = detectStops(deviceId, from, to); - DeviceReportSection deviceStops = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceStops.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceStops.setGroupName(group.getName()); - } - } - deviceStops.setObjects(stops); - devicesStops.add(deviceStops); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesStops); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } - -} diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java new file mode 100644 index 000000000..8dedb9a24 --- /dev/null +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -0,0 +1,100 @@ +/* + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@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.reports; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; + +import org.apache.poi.ss.util.WorkbookUtil; +import org.traccar.Context; +import org.traccar.Main; +import org.traccar.database.DeviceManager; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.reports.model.StopReportItem; +import org.traccar.storage.StorageException; + +public class StopsReportProvider { + + private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { + boolean ignoreOdometer = Context.getDeviceManager() + .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); + + IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); + DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); + + return ReportUtils.detectTripsAndStops( + identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), + Context.getTripsConfig(), ignoreOdometer, StopReportItem.class); + } + + public Collection getObjects( + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList result = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + result.addAll(detectStops(deviceId, from, to)); + } + return result; + } + + public void getExcel( + OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException, IOException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList devicesStops = new ArrayList<>(); + ArrayList sheetNames = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection stops = detectStops(deviceId, from, to); + DeviceReportSection deviceStops = new DeviceReportSection(); + Device device = Context.getIdentityManager().getById(deviceId); + deviceStops.setDeviceName(device.getName()); + sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); + if (device.getGroupId() != 0) { + Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (group != null) { + deviceStops.setGroupName(group.getName()); + } + } + deviceStops.setObjects(stops); + devicesStops.add(deviceStops); + } + String templatePath = Context.getConfig().getString("report.templatesPath", + "templates/export/"); + try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { + org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + jxlsContext.putVar("devices", devicesStops); + jxlsContext.putVar("sheetNames", sheetNames); + jxlsContext.putVar("from", from); + jxlsContext.putVar("to", to); + ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + } + } + +} diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java deleted file mode 100644 index 30c4cb057..000000000 --- a/src/main/java/org/traccar/reports/Summary.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.Date; - -import org.jxls.util.JxlsHelper; -import org.traccar.Context; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.Position; -import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.SummaryReportItem; -import org.traccar.storage.StorageException; - -public final class Summary { - - private Summary() { - } - - private static SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { - SummaryReportItem result = new SummaryReportItem(); - result.setDeviceId(deviceId); - result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); - if (positions != null && !positions.isEmpty()) { - Position firstPosition = null; - Position previousPosition = null; - for (Position position : positions) { - if (firstPosition == null) { - firstPosition = position; - } - previousPosition = position; - if (position.getSpeed() > result.getMaxSpeed()) { - result.setMaxSpeed(position.getSpeed()); - } - } - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - result.setDistance(ReportUtils.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); - result.setSpentFuel(ReportUtils.calculateFuel(firstPosition, previousPosition)); - - long durationMilliseconds; - if (firstPosition.getAttributes().containsKey(Position.KEY_HOURS) - && previousPosition.getAttributes().containsKey(Position.KEY_HOURS)) { - durationMilliseconds = - previousPosition.getLong(Position.KEY_HOURS) - firstPosition.getLong(Position.KEY_HOURS); - result.setEngineHours(durationMilliseconds); - } else { - durationMilliseconds = - previousPosition.getFixTime().getTime() - firstPosition.getFixTime().getTime(); - } - - if (durationMilliseconds > 0) { - result.setAverageSpeed( - UnitsConverter.knotsFromMps(result.getDistance() * 1000 / durationMilliseconds)); - } - - if (!ignoreOdometer - && firstPosition.getDouble(Position.KEY_ODOMETER) != 0 - && previousPosition.getDouble(Position.KEY_ODOMETER) != 0) { - result.setStartOdometer(firstPosition.getDouble(Position.KEY_ODOMETER)); - result.setEndOdometer(previousPosition.getDouble(Position.KEY_ODOMETER)); - } else { - result.setStartOdometer(firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); - result.setEndOdometer(previousPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); - } - - result.setStartTime(firstPosition.getFixTime()); - result.setEndTime(previousPosition.getFixTime()); - } - return result; - } - - private static int getDay(long userId, Date date) { - Calendar calendar = Calendar.getInstance(ReportUtils.getTimezone(userId)); - calendar.setTime(date); - return calendar.get(Calendar.DAY_OF_MONTH); - } - - private static Collection calculateSummaryResults( - long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { - - ArrayList positions = new ArrayList<>(Context.getDataManager().getPositions(deviceId, from, to)); - - ArrayList results = new ArrayList<>(); - if (daily && !positions.isEmpty()) { - int startIndex = 0; - int startDay = getDay(userId, positions.iterator().next().getFixTime()); - for (int i = 0; i < positions.size(); i++) { - int currentDay = getDay(userId, positions.get(i).getFixTime()); - if (currentDay != startDay) { - results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, i))); - startIndex = i; - startDay = currentDay; - } - } - results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, positions.size()))); - } else { - results.add(calculateSummaryResult(deviceId, positions)); - } - - return results; - } - - public static Collection getObjects(long userId, Collection deviceIds, - Collection groupIds, Date from, Date to, boolean daily) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); - for (SummaryReportItem summaryReport : deviceResults) { - if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { - result.add(summaryReport); - } - } - } - return result; - } - - public static void getExcel(OutputStream outputStream, - long userId, Collection deviceIds, Collection groupIds, - Date from, Date to, boolean daily) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); - Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("summaries", summaries); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - JxlsHelper.getInstance().setUseFastFormulaProcessor(false) - .processTemplate(inputStream, outputStream, jxlsContext); - } - } -} diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java new file mode 100644 index 000000000..a2306f3d1 --- /dev/null +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -0,0 +1,155 @@ +/* + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Andrey Kunitsyn (andrey@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.reports; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; + +import org.jxls.util.JxlsHelper; +import org.traccar.Context; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.SummaryReportItem; +import org.traccar.storage.StorageException; + +public class SummaryReportProvider { + + private SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { + SummaryReportItem result = new SummaryReportItem(); + result.setDeviceId(deviceId); + result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); + if (positions != null && !positions.isEmpty()) { + Position firstPosition = null; + Position previousPosition = null; + for (Position position : positions) { + if (firstPosition == null) { + firstPosition = position; + } + previousPosition = position; + if (position.getSpeed() > result.getMaxSpeed()) { + result.setMaxSpeed(position.getSpeed()); + } + } + boolean ignoreOdometer = Context.getDeviceManager() + .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); + result.setDistance(ReportUtils.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); + result.setSpentFuel(ReportUtils.calculateFuel(firstPosition, previousPosition)); + + long durationMilliseconds; + if (firstPosition.getAttributes().containsKey(Position.KEY_HOURS) + && previousPosition.getAttributes().containsKey(Position.KEY_HOURS)) { + durationMilliseconds = + previousPosition.getLong(Position.KEY_HOURS) - firstPosition.getLong(Position.KEY_HOURS); + result.setEngineHours(durationMilliseconds); + } else { + durationMilliseconds = + previousPosition.getFixTime().getTime() - firstPosition.getFixTime().getTime(); + } + + if (durationMilliseconds > 0) { + result.setAverageSpeed( + UnitsConverter.knotsFromMps(result.getDistance() * 1000 / durationMilliseconds)); + } + + if (!ignoreOdometer + && firstPosition.getDouble(Position.KEY_ODOMETER) != 0 + && previousPosition.getDouble(Position.KEY_ODOMETER) != 0) { + result.setStartOdometer(firstPosition.getDouble(Position.KEY_ODOMETER)); + result.setEndOdometer(previousPosition.getDouble(Position.KEY_ODOMETER)); + } else { + result.setStartOdometer(firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); + result.setEndOdometer(previousPosition.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + + result.setStartTime(firstPosition.getFixTime()); + result.setEndTime(previousPosition.getFixTime()); + } + return result; + } + + private int getDay(long userId, Date date) { + Calendar calendar = Calendar.getInstance(ReportUtils.getTimezone(userId)); + calendar.setTime(date); + return calendar.get(Calendar.DAY_OF_MONTH); + } + + private Collection calculateSummaryResults( + long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { + + ArrayList positions = new ArrayList<>(Context.getDataManager().getPositions(deviceId, from, to)); + + ArrayList results = new ArrayList<>(); + if (daily && !positions.isEmpty()) { + int startIndex = 0; + int startDay = getDay(userId, positions.iterator().next().getFixTime()); + for (int i = 0; i < positions.size(); i++) { + int currentDay = getDay(userId, positions.get(i).getFixTime()); + if (currentDay != startDay) { + results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, i))); + startIndex = i; + startDay = currentDay; + } + } + results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, positions.size()))); + } else { + results.add(calculateSummaryResult(deviceId, positions)); + } + + return results; + } + + public Collection getObjects( + long userId, Collection deviceIds, + Collection groupIds, Date from, Date to, boolean daily) throws StorageException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList result = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); + for (SummaryReportItem summaryReport : deviceResults) { + if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { + result.add(summaryReport); + } + } + } + return result; + } + + public void getExcel(OutputStream outputStream, + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to, boolean daily) throws StorageException, IOException { + ReportUtils.checkPeriodLimit(from, to); + Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); + String templatePath = Context.getConfig().getString("report.templatesPath", + "templates/export/"); + try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { + org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + jxlsContext.putVar("summaries", summaries); + jxlsContext.putVar("from", from); + jxlsContext.putVar("to", to); + JxlsHelper.getInstance().setUseFastFormulaProcessor(false) + .processTemplate(inputStream, outputStream, jxlsContext); + } + } +} diff --git a/src/main/java/org/traccar/reports/Trips.java b/src/main/java/org/traccar/reports/Trips.java deleted file mode 100644 index 74e24cf2f..000000000 --- a/src/main/java/org/traccar/reports/Trips.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2016 Anton Tananaev (anton@traccar.org) - * Copyright 2016 Andrey Kunitsyn (andrey@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.reports; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - -import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.model.DeviceReportSection; -import org.traccar.reports.model.TripReportItem; -import org.traccar.storage.StorageException; - -public final class Trips { - - private Trips() { - } - - private static Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - - IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); - DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - - return ReportUtils.detectTripsAndStops( - identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, TripReportItem.class); - } - - public static Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(detectTrips(deviceId, from, to)); - } - return result; - } - - public static void getExcel(OutputStream outputStream, - long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); - ArrayList devicesTrips = new ArrayList<>(); - ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection trips = detectTrips(deviceId, from, to); - DeviceReportSection deviceTrips = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); - deviceTrips.setDeviceName(device.getName()); - sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); - if (group != null) { - deviceTrips.setGroupName(group.getName()); - } - } - deviceTrips.setObjects(trips); - devicesTrips.add(deviceTrips); - } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); - jxlsContext.putVar("devices", devicesTrips); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); - } - } - -} diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java new file mode 100644 index 000000000..6aff08a1d --- /dev/null +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -0,0 +1,98 @@ +/* + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Andrey Kunitsyn (andrey@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.reports; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; + +import org.apache.poi.ss.util.WorkbookUtil; +import org.traccar.Context; +import org.traccar.Main; +import org.traccar.database.DeviceManager; +import org.traccar.database.IdentityManager; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.model.DeviceReportSection; +import org.traccar.reports.model.TripReportItem; +import org.traccar.storage.StorageException; + +public class TripsReportProvider { + + private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { + boolean ignoreOdometer = Context.getDeviceManager() + .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); + + IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); + DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); + + return ReportUtils.detectTripsAndStops( + identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), + Context.getTripsConfig(), ignoreOdometer, TripReportItem.class); + } + + public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList result = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + result.addAll(detectTrips(deviceId, from, to)); + } + return result; + } + + public void getExcel(OutputStream outputStream, + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException, IOException { + ReportUtils.checkPeriodLimit(from, to); + ArrayList devicesTrips = new ArrayList<>(); + ArrayList sheetNames = new ArrayList<>(); + for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + Collection trips = detectTrips(deviceId, from, to); + DeviceReportSection deviceTrips = new DeviceReportSection(); + Device device = Context.getIdentityManager().getById(deviceId); + deviceTrips.setDeviceName(device.getName()); + sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); + if (device.getGroupId() != 0) { + Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (group != null) { + deviceTrips.setGroupName(group.getName()); + } + } + deviceTrips.setObjects(trips); + devicesTrips.add(deviceTrips); + } + String templatePath = Context.getConfig().getString("report.templatesPath", + "templates/export/"); + try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { + org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + jxlsContext.putVar("devices", devicesTrips); + jxlsContext.putVar("sheetNames", sheetNames); + jxlsContext.putVar("from", from); + jxlsContext.putVar("to", to); + ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + } + } + +} -- cgit v1.2.3 From e41c234ae93c6cc1b43f1e78af8566f288e0c10e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 11:02:22 -0700 Subject: Inject storage for events report --- .../java/org/traccar/reports/EventsReportProvider.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index c4b0aad86..9b4a7df2b 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -38,11 +38,19 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class EventsReportProvider { + private final Storage storage; + + @Inject + public EventsReportProvider(Storage storage) { + this.storage = storage; + } + public Collection getObjects( - Storage storage, long userId, - Collection deviceIds, Collection groupIds, + long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); @@ -66,8 +74,7 @@ public class EventsReportProvider { } public void getExcel( - OutputStream outputStream, Storage storage, long userId, - Collection deviceIds, Collection groupIds, + OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { ReportUtils.checkPeriodLimit(from, to); ArrayList devicesEvents = new ArrayList<>(); -- cgit v1.2.3 From b6ec84dbb4e1e2e212b0d6195920407a43919ab5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 11:03:59 -0700 Subject: Fix compilation issue --- src/main/java/org/traccar/api/resource/ReportResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 38eb52685..96b32a4f0 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -143,7 +143,7 @@ public class ReportResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - return eventsReportProvider.getObjects(storage, getUserId(), deviceIds, groupIds, types, from, to); + return eventsReportProvider.getObjects(getUserId(), deviceIds, groupIds, types, from, to); } @Path("events") @@ -157,7 +157,7 @@ public class ReportResource extends BaseResource { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); - eventsReportProvider.getExcel(stream, storage, getUserId(), deviceIds, groupIds, types, from, to); + eventsReportProvider.getExcel(stream, getUserId(), deviceIds, groupIds, types, from, to); }); } -- cgit v1.2.3 From 3b5c04b4ddf71223371815575fa1b652fea1d5da Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 4 Jun 2022 20:15:03 -0700 Subject: Handle modern app paths --- src/main/java/org/traccar/web/WebServer.java | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 0ed5d013e..9af9fd33a 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -68,16 +68,17 @@ import java.io.File; import java.io.IOException; import java.io.Writer; import java.net.InetSocketAddress; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.EnumSet; public class WebServer implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); - private Server server; - - private void initServer(Config config) { + private final Server server; + public WebServer(Config config) { String address = config.getString(Keys.WEB_ADDRESS); int port = config.getInteger(Keys.WEB_PORT); if (address == null) { @@ -85,11 +86,6 @@ public class WebServer implements LifecycleObject { } else { server = new Server(new InetSocketAddress(address, port)); } - } - - public WebServer(Config config) { - - initServer(config); ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); @@ -106,8 +102,13 @@ public class WebServer implements LifecycleObject { @Override protected void handleErrorPage( HttpServletRequest request, Writer writer, int code, String message) throws IOException { - writer.write("Error" - + code + " - " + HttpStatus.getMessage(code) + ""); + if (code == HttpStatus.NOT_FOUND_404 && request.getPathInfo().startsWith("/modern")) { + writer.write(Files.readString( + Paths.get(config.getString(Keys.WEB_PATH), "modern", "index.html"))); + } else { + writer.write("Error" + + code + " - " + HttpStatus.getMessage(code) + ""); + } } }); -- cgit v1.2.3 From 59bbaa37656d1aacd7df21d70ec5bfa85cf98608 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 6 Jun 2022 19:05:20 -0700 Subject: Handle missing cache (fix #4861) --- src/main/java/org/traccar/session/cache/CacheManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index aca3df52d..102a31ecd 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -69,7 +69,8 @@ public class CacheManager { public T getObject(Class clazz, long id) { try { lock.readLock().lock(); - return deviceCache.get(new CacheKey(clazz, id)).getValue(); + var cacheValue = deviceCache.get(new CacheKey(clazz, id)); + return cacheValue != null ? cacheValue.getValue() : null; } finally { lock.readLock().unlock(); } -- cgit v1.2.3 From 669bdccecff50eaca46c815598df092ad0fe143d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 6 Jun 2022 19:19:48 -0700 Subject: Simplify logs config --- src/main/java/org/traccar/config/Keys.java | 7 ------- src/main/java/org/traccar/web/WebServer.java | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index f5370874d..ba576397b 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1198,13 +1198,6 @@ public final class Keys { "location.longitudeHemisphere", Collections.singletonList(KeyType.GLOBAL)); - /** - * Enable Jetty Request Log. - */ - public static final ConfigKey WEB_REQUEST_LOG_ENABLE = new ConfigKey<>( - "web.requestLog.enable", - Collections.singletonList(KeyType.GLOBAL)); - /** * Jetty Request Log Path. * The path must include the string "yyyy_mm_dd", which is replaced with the actual date when creating and rolling diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 9af9fd33a..06676fb41 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -118,7 +118,7 @@ public class WebServer implements LifecycleObject { handlers.addHandler(new GzipHandler()); server.setHandler(handlers); - if (config.getBoolean(Keys.WEB_REQUEST_LOG_ENABLE)) { + if (config.hasKey(Keys.WEB_REQUEST_LOG_PATH)) { RequestLogWriter logWriter = new RequestLogWriter(config.getString(Keys.WEB_REQUEST_LOG_PATH)); logWriter.setAppend(true); logWriter.setRetainDays(config.getInteger(Keys.WEB_REQUEST_LOG_RETAIN_DAYS)); -- cgit v1.2.3 From 8eecfdcf5c59f92158a6c339d1622e0e9d67968c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 06:48:53 -0700 Subject: Pass user to notificators --- .../java/org/traccar/api/resource/NotificationResource.java | 12 ++++++++---- src/main/java/org/traccar/api/resource/PasswordResource.java | 2 +- src/main/java/org/traccar/api/resource/ReportResource.java | 4 +++- .../java/org/traccar/api/security/PermissionsService.java | 4 ++-- src/main/java/org/traccar/database/MailManager.java | 10 ++++------ src/main/java/org/traccar/database/NotificationManager.java | 4 +++- .../java/org/traccar/notification/NotificationFormatter.java | 9 ++++----- src/main/java/org/traccar/notificators/Notificator.java | 9 +++++---- .../java/org/traccar/notificators/NotificatorFirebase.java | 11 +++++------ src/main/java/org/traccar/notificators/NotificatorMail.java | 9 +++++---- src/main/java/org/traccar/notificators/NotificatorNull.java | 7 ++++--- .../java/org/traccar/notificators/NotificatorPushover.java | 12 +++++------- src/main/java/org/traccar/notificators/NotificatorSms.java | 12 +++++------- .../java/org/traccar/notificators/NotificatorTelegram.java | 11 +++++------ src/main/java/org/traccar/notificators/NotificatorWeb.java | 7 ++++--- 15 files changed, 63 insertions(+), 60 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index cf4b66fa1..2fc103e20 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -31,7 +31,9 @@ import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Event; import org.traccar.model.Notification; import org.traccar.model.Typed; +import org.traccar.model.User; import org.traccar.notification.MessageException; +import org.traccar.storage.StorageException; @Path("notifications") @Produces(MediaType.APPLICATION_JSON) @@ -56,10 +58,11 @@ public class NotificationResource extends ExtendedObjectResource { @POST @Path("test") - public Response testMessage() throws MessageException, InterruptedException { + public Response testMessage() throws MessageException, InterruptedException, StorageException { + User user = permissionsService.getUser(getUserId()); for (Typed method : Context.getNotificatorManager().getAllNotificatorTypes()) { Context.getNotificatorManager() - .getNotificator(method.getType()).sendSync(getUserId(), new Event("test", 0), null); + .getNotificator(method.getType()).sendSync(user, new Event("test", 0), null); } return Response.noContent().build(); } @@ -67,8 +70,9 @@ public class NotificationResource extends ExtendedObjectResource { @POST @Path("test/{notificator}") public Response testMessage(@PathParam("notificator") String notificator) - throws MessageException, InterruptedException { - Context.getNotificatorManager().getNotificator(notificator).sendSync(getUserId(), new Event("test", 0), null); + throws MessageException, InterruptedException, StorageException { + User user = permissionsService.getUser(getUserId()); + Context.getNotificatorManager().getNotificator(notificator).sendSync(user, new Event("test", 0), null); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 0642ff3cc..ed7131718 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -55,7 +55,7 @@ public class PasswordResource extends BaseResource { velocityContext.put("token", token); NotificationMessage fullMessage = TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); - Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); + Context.getMailManager().sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); break; } } diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 96b32a4f0..3c1b8f715 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -43,6 +43,7 @@ import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.reports.EventsReportProvider; import org.traccar.reports.SummaryReportProvider; @@ -97,8 +98,9 @@ public class ReportResource extends BaseResource { attachment.setDataHandler(new DataHandler(new ByteArrayDataSource( stream.toByteArray(), "application/octet-stream"))); + User user = permissionsService.getUser(userId); Context.getMailManager().sendMessage( - userId, "Report", "The report is in the attachment.", attachment); + user, "Report", "The report is in the attachment.", attachment); } catch (StorageException | IOException | MessagingException e) { LOGGER.warn("Report failed", e); } diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 12a2189e9..9ec3b43c1 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -46,7 +46,7 @@ public class PermissionsService { this.storage = storage; } - private Server getServer() throws StorageException { + public Server getServer() throws StorageException { if (server == null) { server = storage.getObject( Server.class, new Request(new Columns.All())); @@ -54,7 +54,7 @@ public class PermissionsService { return server; } - private User getUser(long userId) throws StorageException { + public User getUser(long userId) throws StorageException { if (user == null) { user = storage.getObject( User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index d94f55cda..21fee5ee7 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -92,14 +92,12 @@ public final class MailManager { } public void sendMessage( - long userId, String subject, String body) throws MessagingException { - sendMessage(userId, subject, body, null); + User user, String subject, String body) throws MessagingException { + sendMessage(user, subject, body, null); } public void sendMessage( - long userId, String subject, String body, MimeBodyPart attachment) throws MessagingException { - User user = Context.getPermissionsManager().getUser(userId); - + User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { Properties properties = null; if (!Context.getConfig().getBoolean("mail.smtp.ignoreUserConfig")) { properties = getProperties(new PropertiesProvider(user)); diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 64f3b6775..f88b3b18c 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -35,6 +35,7 @@ import org.traccar.model.Event; import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.Typed; +import org.traccar.model.User; import org.traccar.storage.StorageException; public class NotificationManager extends ExtendedObjectManager { @@ -106,8 +107,9 @@ public class NotificationManager extends ExtendedObjectManager { .getAddress(position.getLatitude(), position.getLongitude(), null)); } + User user = Context.getUsersManager().getById(userId); for (String notificator : notificators) { - Context.getNotificatorManager().getNotificator(notificator).sendAsync(userId, event, position); + Context.getNotificatorManager().getNotificator(notificator).sendAsync(user, event, position); } } if (Context.getEventForwarder() != null) { diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 30a862372..c3e37c9e9 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -33,9 +33,8 @@ public final class NotificationFormatter { } public static NotificationMessage formatMessage( - CacheManager cacheManager, long userId, Event event, Position position, String templatePath) { + CacheManager cacheManager, User user, Event event, Position position, String templatePath) { - User user = cacheManager.getObject(User.class, userId); Device device = cacheManager.getObject(Device.class, event.getDeviceId()); VelocityContext velocityContext = TextTemplateFormatter.prepareContext(user); @@ -44,9 +43,9 @@ public final class NotificationFormatter { velocityContext.put("event", event); if (position != null) { velocityContext.put("position", position); - velocityContext.put("speedUnit", ReportUtils.getSpeedUnit(userId)); - velocityContext.put("distanceUnit", ReportUtils.getDistanceUnit(userId)); - velocityContext.put("volumeUnit", ReportUtils.getVolumeUnit(userId)); + velocityContext.put("speedUnit", ReportUtils.getSpeedUnit(user.getId())); + velocityContext.put("distanceUnit", ReportUtils.getDistanceUnit(user.getId())); + velocityContext.put("volumeUnit", ReportUtils.getVolumeUnit(user.getId())); } if (event.getGeofenceId() != 0) { velocityContext.put("geofence", cacheManager.getObject(Geofence.class, event.getGeofenceId())); diff --git a/src/main/java/org/traccar/notificators/Notificator.java b/src/main/java/org/traccar/notificators/Notificator.java index dd888bae9..3903f3008 100644 --- a/src/main/java/org/traccar/notificators/Notificator.java +++ b/src/main/java/org/traccar/notificators/Notificator.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,23 +20,24 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.notification.MessageException; public abstract class Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(Notificator.class); - public void sendAsync(final long userId, final Event event, final Position position) { + public void sendAsync(User user, Event event, Position position) { new Thread(() -> { try { - sendSync(userId, event, position); + sendSync(user, event, position); } catch (MessageException | InterruptedException error) { LOGGER.warn("Event send error", error); } }).start(); } - public abstract void sendSync(long userId, Event event, Position position) + public abstract void sendSync(User user, Event event, Position position) throws MessageException, InterruptedException; } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index bcce9a4d8..ee22b3a22 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -67,12 +67,11 @@ public class NotificatorFirebase extends Notificator { } @Override - public void sendSync(long userId, Event event, Position position) { - final User user = Context.getPermissionsManager().getUser(userId); + public void sendSync(User user, Event event, Position position) { if (user.getAttributes().containsKey("notificationTokens")) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); Notification notification = new Notification(); notification.title = shortMessage.getSubject(); @@ -99,8 +98,8 @@ public class NotificatorFirebase extends Notificator { } @Override - public void sendAsync(long userId, Event event, Position position) { - sendSync(userId, event, position); + public void sendAsync(User user, Event event, Position position) { + sendSync(user, event, position); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index eb7f399eb..7b85254be 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,6 +20,7 @@ import org.traccar.Context; import org.traccar.Main; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.notification.NotificationMessage; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; @@ -30,11 +31,11 @@ import javax.mail.MessagingException; public final class NotificatorMail extends Notificator { @Override - public void sendSync(long userId, Event event, Position position) throws MessageException { + public void sendSync(User user, Event event, Position position) throws MessageException { try { NotificationMessage fullMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "full"); - Context.getMailManager().sendMessage(userId, fullMessage.getSubject(), fullMessage.getBody()); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "full"); + Context.getMailManager().sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); } diff --git a/src/main/java/org/traccar/notificators/NotificatorNull.java b/src/main/java/org/traccar/notificators/NotificatorNull.java index 9364336be..a03a6e2c9 100644 --- a/src/main/java/org/traccar/notificators/NotificatorNull.java +++ b/src/main/java/org/traccar/notificators/NotificatorNull.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,18 +20,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; public final class NotificatorNull extends Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorNull.class); @Override - public void sendAsync(long userId, Event event, Position position) { + public void sendAsync(User user, Event event, Position position) { LOGGER.warn("You are using null notificatior, please check your configuration, notification not sent"); } @Override - public void sendSync(long userId, Event event, Position position) { + public void sendSync(User user, Event event, Position position) { LOGGER.warn("You are using null notificatior, please check your configuration, notification not sent"); } diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 73fad9bd2..ffd9b426f 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@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,9 +59,7 @@ public class NotificatorPushover extends Notificator { } @Override - public void sendSync(long userId, Event event, Position position) { - - final User user = Context.getPermissionsManager().getUser(userId); + public void sendSync(User user, Event event, Position position) { String device = ""; @@ -80,7 +78,7 @@ public class NotificatorPushover extends Notificator { } NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); Message message = new Message(); message.token = token; @@ -103,8 +101,8 @@ public class NotificatorPushover extends Notificator { } @Override - public void sendAsync(long userId, Event event, Position position) { - sendSync(userId, event, position); + public void sendAsync(User user, Event event, Position position) { + sendSync(user, event, position); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index 09eb65b0c..ae409c558 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,11 +30,10 @@ import org.traccar.session.cache.CacheManager; public final class NotificatorSms extends Notificator { @Override - public void sendAsync(long userId, Event event, Position position) { - final User user = Context.getPermissionsManager().getUser(userId); + public void sendAsync(User user, Event event, Position position) { if (user.getPhone() != null) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageAsync(user.getPhone(), shortMessage.getBody(), false); @@ -42,11 +41,10 @@ public final class NotificatorSms extends Notificator { } @Override - public void sendSync(long userId, Event event, Position position) throws MessageException, InterruptedException { - final User user = Context.getPermissionsManager().getUser(userId); + public void sendSync(User user, Event event, Position position) throws MessageException, InterruptedException { if (user.getPhone() != null) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); Context.getSmsManager().sendMessageSync(user.getPhone(), shortMessage.getBody(), false); diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index a8e69e77d..46e29559d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2021 Rafael Miquelino (rafaelmiquelino@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -99,10 +99,9 @@ public class NotificatorTelegram extends Notificator { } @Override - public void sendSync(long userId, Event event, Position position) { - User user = Context.getPermissionsManager().getUser(userId); + public void sendSync(User user, Event event, Position position) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), userId, event, position, "short"); + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); @@ -117,8 +116,8 @@ public class NotificatorTelegram extends Notificator { } @Override - public void sendAsync(long userId, Event event, Position position) { - sendSync(userId, event, position); + public void sendAsync(User user, Event event, Position position) { + sendSync(user, event, position); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 1d11c0b46..c9ab93b6d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,12 +19,13 @@ package org.traccar.notificators; import org.traccar.Context; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; public final class NotificatorWeb extends Notificator { @Override - public void sendSync(long userId, Event event, Position position) { - Context.getConnectionManager().updateEvent(userId, event); + public void sendSync(User user, Event event, Position position) { + Context.getConnectionManager().updateEvent(user.getId(), event); } } -- cgit v1.2.3 From 65f9e253171dc6805127e5279b97fad05f8c4b9f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 07:07:25 -0700 Subject: Remove async methods --- src/main/java/org/traccar/BaseProtocol.java | 4 +-- .../traccar/api/resource/NotificationResource.java | 4 +-- .../java/org/traccar/database/CommandsManager.java | 2 +- .../org/traccar/database/NotificationManager.java | 13 +++++++-- .../java/org/traccar/notificators/Notificator.java | 19 ++----------- .../traccar/notificators/NotificatorFirebase.java | 9 ++---- .../org/traccar/notificators/NotificatorMail.java | 4 +-- .../org/traccar/notificators/NotificatorNull.java | 9 ++---- .../traccar/notificators/NotificatorPushover.java | 9 ++---- .../org/traccar/notificators/NotificatorSms.java | 18 ++---------- .../traccar/notificators/NotificatorTelegram.java | 9 ++---- .../org/traccar/notificators/NotificatorWeb.java | 4 +-- src/main/java/org/traccar/sms/HttpSmsClient.java | 32 +++++----------------- src/main/java/org/traccar/sms/SmsManager.java | 7 ++--- src/main/java/org/traccar/sms/SnsSmsClient.java | 9 ++---- 15 files changed, 43 insertions(+), 109 deletions(-) diff --git a/src/main/java/org/traccar/BaseProtocol.java b/src/main/java/org/traccar/BaseProtocol.java index 52d34dc44..ec1933dc8 100644 --- a/src/main/java/org/traccar/BaseProtocol.java +++ b/src/main/java/org/traccar/BaseProtocol.java @@ -113,11 +113,11 @@ public abstract class BaseProtocol implements Protocol { public void sendTextCommand(String destAddress, Command command) throws Exception { if (Context.getSmsManager() != null) { if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmsManager().sendMessageSync(destAddress, command.getString(Command.KEY_DATA), true); + Context.getSmsManager().sendMessage(destAddress, command.getString(Command.KEY_DATA), true); } else if (supportedTextCommands.contains(command.getType()) && textCommandEncoder != null) { String encodedCommand = (String) textCommandEncoder.encodeCommand(command); if (encodedCommand != null) { - Context.getSmsManager().sendMessageSync(destAddress, encodedCommand, true); + Context.getSmsManager().sendMessage(destAddress, encodedCommand, true); } else { throw new RuntimeException("Failed to encode command"); } diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index 2fc103e20..9ea811473 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -62,7 +62,7 @@ public class NotificationResource extends ExtendedObjectResource { User user = permissionsService.getUser(getUserId()); for (Typed method : Context.getNotificatorManager().getAllNotificatorTypes()) { Context.getNotificatorManager() - .getNotificator(method.getType()).sendSync(user, new Event("test", 0), null); + .getNotificator(method.getType()).send(user, new Event("test", 0), null); } return Response.noContent().build(); } @@ -72,7 +72,7 @@ public class NotificationResource extends ExtendedObjectResource { public Response testMessage(@PathParam("notificator") String notificator) throws MessageException, InterruptedException, StorageException { User user = permissionsService.getUser(getUserId()); - Context.getNotificatorManager().getNotificator(notificator).sendSync(user, new Event("test", 0), null); + Context.getNotificatorManager().getNotificator(notificator).send(user, new Event("test", 0), null); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index d440755f7..8dd2ba8b7 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -79,7 +79,7 @@ public class CommandsManager { BaseProtocol protocol = serverManager.getProtocol(position.getProtocol()); protocol.sendTextCommand(device.getPhone(), command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - smsManager.sendMessageSync(device.getPhone(), command.getString(Command.KEY_DATA), true); + smsManager.sendMessage(device.getPhone(), command.getString(Command.KEY_DATA), true); } else { throw new RuntimeException("Command " + command.getType() + " is not supported"); } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index f88b3b18c..2f912fff1 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -36,6 +36,7 @@ import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.Typed; import org.traccar.model.User; +import org.traccar.notification.MessageException; import org.traccar.storage.StorageException; public class NotificationManager extends ExtendedObjectManager { @@ -108,9 +109,15 @@ public class NotificationManager extends ExtendedObjectManager { } User user = Context.getUsersManager().getById(userId); - for (String notificator : notificators) { - Context.getNotificatorManager().getNotificator(notificator).sendAsync(user, event, position); - } + new Thread(() -> { + for (String notificator : notificators) { + try { + Context.getNotificatorManager().getNotificator(notificator).send(user, event, position); + } catch (MessageException | InterruptedException exception) { + LOGGER.warn("Notification failed", exception); + } + } + }).start(); } if (Context.getEventForwarder() != null) { Context.getEventForwarder().forwardEvent(event, position, usersToForward); diff --git a/src/main/java/org/traccar/notificators/Notificator.java b/src/main/java/org/traccar/notificators/Notificator.java index 3903f3008..052365c7a 100644 --- a/src/main/java/org/traccar/notificators/Notificator.java +++ b/src/main/java/org/traccar/notificators/Notificator.java @@ -16,28 +16,13 @@ */ package org.traccar.notificators; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.MessageException; -public abstract class Notificator { +public interface Notificator { - private static final Logger LOGGER = LoggerFactory.getLogger(Notificator.class); - - public void sendAsync(User user, Event event, Position position) { - new Thread(() -> { - try { - sendSync(user, event, position); - } catch (MessageException | InterruptedException error) { - LOGGER.warn("Event send error", error); - } - }).start(); - } - - public abstract void sendSync(User user, Event event, Position position) - throws MessageException, InterruptedException; + void send(User user, Event event, Position position) throws MessageException, InterruptedException; } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index ee22b3a22..cafd2237d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -32,7 +32,7 @@ import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; -public class NotificatorFirebase extends Notificator { +public class NotificatorFirebase implements Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorFirebase.class); @@ -67,7 +67,7 @@ public class NotificatorFirebase extends Notificator { } @Override - public void sendSync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) { if (user.getAttributes().containsKey("notificationTokens")) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( @@ -97,9 +97,4 @@ public class NotificatorFirebase extends Notificator { } } - @Override - public void sendAsync(User user, Event event, Position position) { - sendSync(user, event, position); - } - } diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 7b85254be..fd7cae7c3 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -28,10 +28,10 @@ import org.traccar.session.cache.CacheManager; import javax.mail.MessagingException; -public final class NotificatorMail extends Notificator { +public final class NotificatorMail implements Notificator { @Override - public void sendSync(User user, Event event, Position position) throws MessageException { + public void send(User user, Event event, Position position) throws MessageException { try { NotificationMessage fullMessage = NotificationFormatter.formatMessage( Main.getInjector().getInstance(CacheManager.class), user, event, position, "full"); diff --git a/src/main/java/org/traccar/notificators/NotificatorNull.java b/src/main/java/org/traccar/notificators/NotificatorNull.java index a03a6e2c9..ba9ade9c6 100644 --- a/src/main/java/org/traccar/notificators/NotificatorNull.java +++ b/src/main/java/org/traccar/notificators/NotificatorNull.java @@ -22,17 +22,12 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -public final class NotificatorNull extends Notificator { +public class NotificatorNull implements Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorNull.class); @Override - public void sendAsync(User user, Event event, Position position) { - LOGGER.warn("You are using null notificatior, please check your configuration, notification not sent"); - } - - @Override - public void sendSync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) { LOGGER.warn("You are using null notificatior, please check your configuration, notification not sent"); } diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index ffd9b426f..70c1a6cdc 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -31,7 +31,7 @@ import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; -public class NotificatorPushover extends Notificator { +public class NotificatorPushover implements Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorPushover.class); @@ -59,7 +59,7 @@ public class NotificatorPushover extends Notificator { } @Override - public void sendSync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) { String device = ""; @@ -100,9 +100,4 @@ public class NotificatorPushover extends Notificator { }); } - @Override - public void sendAsync(User user, Event event, Position position) { - sendSync(user, event, position); - } - } diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index ae409c558..f35b797cd 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -27,27 +27,15 @@ import org.traccar.notification.NotificationFormatter; import org.traccar.notification.NotificationMessage; import org.traccar.session.cache.CacheManager; -public final class NotificatorSms extends Notificator { +public final class NotificatorSms implements Notificator { @Override - public void sendAsync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) throws MessageException, InterruptedException { if (user.getPhone() != null) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); Main.getInjector().getInstance(StatisticsManager.class).registerSms(); - Context.getSmsManager().sendMessageAsync(user.getPhone(), - shortMessage.getBody(), false); - } - } - - @Override - public void sendSync(User user, Event event, Position position) throws MessageException, InterruptedException { - if (user.getPhone() != null) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); - Main.getInjector().getInstance(StatisticsManager.class).registerSms(); - Context.getSmsManager().sendMessageSync(user.getPhone(), - shortMessage.getBody(), false); + Context.getSmsManager().sendMessage(user.getPhone(), shortMessage.getBody(), false); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 46e29559d..0ed53ac4c 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -32,7 +32,7 @@ import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; -public class NotificatorTelegram extends Notificator { +public class NotificatorTelegram implements Notificator { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorTelegram.class); @@ -99,7 +99,7 @@ public class NotificatorTelegram extends Notificator { } @Override - public void sendSync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); @@ -115,9 +115,4 @@ public class NotificatorTelegram extends Notificator { } } - @Override - public void sendAsync(User user, Event event, Position position) { - sendSync(user, event, position); - } - } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index c9ab93b6d..023cb04af 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -21,10 +21,10 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -public final class NotificatorWeb extends Notificator { +public final class NotificatorWeb implements Notificator { @Override - public void sendSync(User user, Event event, Position position) { + public void send(User user, Event event, Position position) { Context.getConnectionManager().updateEvent(user.getId(), event); } diff --git a/src/main/java/org/traccar/sms/HttpSmsClient.java b/src/main/java/org/traccar/sms/HttpSmsClient.java index 6234eabb8..5c3cef747 100644 --- a/src/main/java/org/traccar/sms/HttpSmsClient.java +++ b/src/main/java/org/traccar/sms/HttpSmsClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,8 +16,6 @@ */ package org.traccar.sms; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.config.Keys; import org.traccar.helper.DataConverter; @@ -25,7 +23,6 @@ import org.traccar.notification.MessageException; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.InvocationCallback; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.UnsupportedEncodingException; @@ -34,8 +31,6 @@ import java.nio.charset.StandardCharsets; public class HttpSmsClient implements SmsManager { - private static final Logger LOGGER = LoggerFactory.getLogger(HttpSmsClient.class); - private final String url; private final String authorizationHeader; private final String authorization; @@ -91,26 +86,13 @@ public class HttpSmsClient implements SmsManager { } @Override - public void sendMessageSync(String destAddress, String message, boolean command) throws MessageException { - Response response = getRequestBuilder().post(Entity.entity(preparePayload(destAddress, message), mediaType)); - if (response.getStatus() / 100 != 2) { - throw new MessageException(response.readEntity(String.class)); - } - } - - @Override - public void sendMessageAsync(final String destAddress, final String message, final boolean command) { - getRequestBuilder().async().post( - Entity.entity(preparePayload(destAddress, message), mediaType), new InvocationCallback() { - @Override - public void completed(String s) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("SMS send failed", throwable); + public void sendMessage(String destAddress, String message, boolean command) throws MessageException { + try (Response response = getRequestBuilder() + .post(Entity.entity(preparePayload(destAddress, message), mediaType))) { + if (response.getStatus() / 100 != 2) { + throw new MessageException(response.readEntity(String.class)); } - }); + } } } diff --git a/src/main/java/org/traccar/sms/SmsManager.java b/src/main/java/org/traccar/sms/SmsManager.java index 3b0cbda7f..9ab25d9cb 100644 --- a/src/main/java/org/traccar/sms/SmsManager.java +++ b/src/main/java/org/traccar/sms/SmsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,10 +20,7 @@ import org.traccar.notification.MessageException; public interface SmsManager { - void sendMessageSync( + void sendMessage( String destAddress, String message, boolean command) throws InterruptedException, MessageException; - void sendMessageAsync( - String destAddress, String message, boolean command); - } diff --git a/src/main/java/org/traccar/sms/SnsSmsClient.java b/src/main/java/org/traccar/sms/SnsSmsClient.java index bdd4104f5..49889ac89 100644 --- a/src/main/java/org/traccar/sms/SnsSmsClient.java +++ b/src/main/java/org/traccar/sms/SnsSmsClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2021 Subodh Ranadive (subodhranadive3103@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -54,7 +54,7 @@ public class SnsSmsClient implements SmsManager { } @Override - public void sendMessageSync(String destAddress, String message, boolean command) { + public void sendMessage(String destAddress, String message, boolean command) { Map smsAttributes = new HashMap<>(); smsAttributes.put("AWS.SNS.SMS.SenderID", new MessageAttributeValue().withStringValue("SNS").withDataType("String")); @@ -74,9 +74,4 @@ public class SnsSmsClient implements SmsManager { } }); } - - @Override - public void sendMessageAsync(String destAddress, String message, boolean command) { - sendMessageSync(destAddress, message, command); - } } -- cgit v1.2.3 From 3a83acbf92741b34323a74bd1a233186d507c46b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 07:16:51 -0700 Subject: Send formatted event message --- .../org/traccar/notificators/NotificatorWeb.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 023cb04af..e19a94c1d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -17,15 +17,34 @@ package org.traccar.notificators; import org.traccar.Context; +import org.traccar.Main; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; +import org.traccar.notification.NotificationFormatter; +import org.traccar.notification.NotificationMessage; +import org.traccar.session.cache.CacheManager; public final class NotificatorWeb implements Notificator { @Override public void send(User user, Event event, Position position) { - Context.getConnectionManager().updateEvent(user.getId(), event); + + Event copy = new Event(); + copy.setId(event.getId()); + copy.setDeviceId(event.getDeviceId()); + copy.setType(event.getType()); + copy.setEventTime(event.getEventTime()); + copy.setPositionId(event.getPositionId()); + copy.setGeofenceId(event.getGeofenceId()); + copy.setMaintenanceId(event.getMaintenanceId()); + copy.getAttributes().putAll(event.getAttributes()); + + NotificationMessage message = NotificationFormatter.formatMessage( + Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); + copy.set("message", message.getBody()); + + Context.getConnectionManager().updateEvent(user.getId(), copy); } } -- cgit v1.2.3 From 79cc136a4e8394cf340277ff2a912e97b89d5c59 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 08:22:55 -0700 Subject: Remove calendar manager --- src/main/java/org/traccar/Context.java | 14 ++--------- src/main/java/org/traccar/MainModule.java | 6 ----- .../java/org/traccar/database/CalendarManager.java | 27 ---------------------- .../org/traccar/database/NotificationManager.java | 8 +++++-- .../org/traccar/database/PermissionsManager.java | 4 ---- .../handler/events/GeofenceEventHandler.java | 12 +++++----- 6 files changed, 14 insertions(+), 57 deletions(-) delete mode 100644 src/main/java/org/traccar/database/CalendarManager.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index dde98f505..e5a0c640f 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -24,7 +24,6 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; -import org.traccar.database.CalendarManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.DriversManager; @@ -39,7 +38,6 @@ import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -50,6 +48,7 @@ import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; import org.traccar.reports.common.TripsConfig; import org.traccar.session.ConnectionManager; +import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; @@ -149,12 +148,6 @@ public final class Context { return geofenceManager; } - private static CalendarManager calendarManager; - - public static CalendarManager getCalendarManager() { - return calendarManager; - } - private static NotificationManager notificationManager; public static NotificationManager getNotificationManager() { @@ -291,8 +284,7 @@ public final class Context { private static void initEventsModule() { geofenceManager = new GeofenceManager(dataManager); - calendarManager = new CalendarManager(dataManager); - notificationManager = new NotificationManager(dataManager); + notificationManager = new NotificationManager(dataManager, Main.getInjector().getInstance(CacheManager.class)); notificatorManager = new NotificatorManager(); Properties velocityProperties = new Properties(); velocityProperties.setProperty("file.resource.loader.path", @@ -330,8 +322,6 @@ public final class Context { return (BaseObjectManager) groupsManager; } else if (clazz.equals(User.class)) { return (BaseObjectManager) usersManager; - } else if (clazz.equals(Calendar.class)) { - return (BaseObjectManager) calendarManager; } else if (clazz.equals(Geofence.class)) { return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Driver.class)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index fb70a51c6..b757b99a7 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -23,7 +23,6 @@ import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.CalendarManager; import org.traccar.database.LdapProvider; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; @@ -125,11 +124,6 @@ public class MainModule extends AbstractModule { return Context.getGeofenceManager(); } - @Provides - public static CalendarManager provideCalendarManager() { - return Context.getCalendarManager(); - } - @Provides public static SmsManager provideSmsManager() { return Context.getSmsManager(); diff --git a/src/main/java/org/traccar/database/CalendarManager.java b/src/main/java/org/traccar/database/CalendarManager.java deleted file mode 100644 index 44ced1082..000000000 --- a/src/main/java/org/traccar/database/CalendarManager.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@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.database; - -import org.traccar.model.Calendar; - -public class CalendarManager extends SimpleObjectManager { - - public CalendarManager(DataManager dataManager) { - super(dataManager, Calendar.class); - } - -} diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 2f912fff1..fcefb54f0 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -37,16 +37,20 @@ import org.traccar.model.Position; import org.traccar.model.Typed; import org.traccar.model.User; import org.traccar.notification.MessageException; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; public class NotificationManager extends ExtendedObjectManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); + private final CacheManager cacheManager; + private final boolean geocodeOnRequest; - public NotificationManager(DataManager dataManager) { + public NotificationManager(DataManager dataManager, CacheManager cacheManager) { super(dataManager, Notification.class); + this.cacheManager = cacheManager; geocodeOnRequest = Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST); } @@ -56,7 +60,7 @@ public class NotificationManager extends ExtendedObjectManager { for (long itemId : getUserItems(userId)) { if (getById(itemId).getAlways() || deviceNotifications.contains(itemId)) { long calendarId = getById(itemId).getCalendarId(); - Calendar calendar = calendarId != 0 ? Context.getCalendarManager().getById(calendarId) : null; + Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; if (calendar == null || calendar.checkMoment(time)) { result.add(itemId); } diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 61b35b380..544faf697 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -19,7 +19,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -361,7 +360,6 @@ public class PermissionsManager { if (Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshUserItems(); } - Context.getCalendarManager().refreshUserItems(); Context.getDriversManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -387,8 +385,6 @@ public class PermissionsManager { Context.getGeofenceManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Driver.class)) { Context.getDriversManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Calendar.class)) { - Context.getCalendarManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index c7dcf3f59..17e240f68 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; import io.netty.channel.ChannelHandler; -import org.traccar.database.CalendarManager; import org.traccar.session.ConnectionManager; import org.traccar.database.GeofenceManager; import org.traccar.database.IdentityManager; @@ -29,24 +28,25 @@ import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { + private final CacheManager cacheManager; private final IdentityManager identityManager; private final GeofenceManager geofenceManager; - private final CalendarManager calendarManager; private final ConnectionManager connectionManager; @Inject public GeofenceEventHandler( - IdentityManager identityManager, GeofenceManager geofenceManager, CalendarManager calendarManager, + CacheManager cacheManager, IdentityManager identityManager, GeofenceManager geofenceManager, ConnectionManager connectionManager) { + this.cacheManager = cacheManager; this.identityManager = identityManager; this.geofenceManager = geofenceManager; - this.calendarManager = calendarManager; this.connectionManager = connectionManager; } @@ -77,7 +77,7 @@ public class GeofenceEventHandler extends BaseEventHandler { Map events = new HashMap<>(); for (long geofenceId : oldGeofences) { long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); - Calendar calendar = calendarId != 0 ? calendarManager.getById(calendarId) : null; + Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position); event.setGeofenceId(geofenceId); @@ -86,7 +86,7 @@ public class GeofenceEventHandler extends BaseEventHandler { } for (long geofenceId : newGeofences) { long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); - Calendar calendar = calendarId != 0 ? calendarManager.getById(calendarId) : null; + Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position); event.setGeofenceId(geofenceId); -- cgit v1.2.3 From 32b39cffc6dd705e9aacbe5b8d68bc37106997d2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 15:44:08 -0700 Subject: Support TopFlyTech UDP protocol --- src/main/java/org/traccar/protocol/T800xProtocol.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocol.java b/src/main/java/org/traccar/protocol/T800xProtocol.java index fa692c792..a6f5f1514 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,6 +35,13 @@ public class T800xProtocol extends BaseProtocol { pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); } }); + addServer(new TrackerServer(true, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new T800xProtocolEncoder(T800xProtocol.this)); + pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); + } + }); } } -- cgit v1.2.3 From b745e3804950fefd24b38937c90c4d5c61219321 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 16:38:58 -0700 Subject: Remove drivers manager --- schema/changelog-5.1.xml | 17 ++++ schema/changelog-master.xml | 1 + src/main/java/org/traccar/Context.java | 12 --- .../java/org/traccar/database/DriversManager.java | 100 --------------------- .../org/traccar/database/PermissionsManager.java | 7 -- .../notification/NotificationFormatter.java | 3 +- .../org/traccar/reports/StopsReportProvider.java | 12 ++- .../org/traccar/reports/TripsReportProvider.java | 12 ++- .../org/traccar/reports/common/ReportUtils.java | 28 +++--- .../org/traccar/session/cache/CacheManager.java | 7 ++ .../java/org/traccar/reports/ReportUtilsTest.java | 43 ++++----- 11 files changed, 85 insertions(+), 157 deletions(-) create mode 100644 schema/changelog-5.1.xml delete mode 100644 src/main/java/org/traccar/database/DriversManager.java diff --git a/schema/changelog-5.1.xml b/schema/changelog-5.1.xml new file mode 100644 index 000000000..26c2088b9 --- /dev/null +++ b/schema/changelog-5.1.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index bb2b3e2f3..471b0fe5d 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -31,5 +31,6 @@ + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index e5a0c640f..899f8ea54 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -26,7 +26,6 @@ import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.DriversManager; import org.traccar.database.GeofenceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; @@ -39,7 +38,6 @@ import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Notification; @@ -178,12 +176,6 @@ public final class Context { return eventForwarder; } - private static DriversManager driversManager; - - public static DriversManager getDriversManager() { - return driversManager; - } - private static SmsManager smsManager; public static SmsManager getSmsManager() { @@ -277,8 +269,6 @@ public final class Context { eventForwarder = new EventForwarder(config); } - driversManager = new DriversManager(dataManager); - } private static void initEventsModule() { @@ -324,8 +314,6 @@ public final class Context { return (BaseObjectManager) usersManager; } else if (clazz.equals(Geofence.class)) { return (BaseObjectManager) geofenceManager; - } else if (clazz.equals(Driver.class)) { - return (BaseObjectManager) driversManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager) notificationManager; } diff --git a/src/main/java/org/traccar/database/DriversManager.java b/src/main/java/org/traccar/database/DriversManager.java deleted file mode 100644 index d111cd643..000000000 --- a/src/main/java/org/traccar/database/DriversManager.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.database; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.traccar.model.Driver; - -public class DriversManager extends ExtendedObjectManager { - - private Map driversByUniqueId; - - public DriversManager(DataManager dataManager) { - super(dataManager, Driver.class); - try { - writeLock(); - if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(); - } - } finally { - writeUnlock(); - } - } - - private void addByUniqueId(Driver driver) { - try { - writeLock(); - if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(); - } - driversByUniqueId.put(driver.getUniqueId(), driver); - } finally { - writeUnlock(); - } - } - - private void removeByUniqueId(String driverUniqueId) { - try { - writeLock(); - if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(); - } - driversByUniqueId.remove(driverUniqueId); - } finally { - writeUnlock(); - } - } - - @Override - protected void addNewItem(Driver driver) { - super.addNewItem(driver); - addByUniqueId(driver); - } - - @Override - protected void updateCachedItem(Driver driver) { - Driver cachedDriver = getById(driver.getId()); - cachedDriver.setName(driver.getName()); - if (!driver.getUniqueId().equals(cachedDriver.getUniqueId())) { - removeByUniqueId(cachedDriver.getUniqueId()); - cachedDriver.setUniqueId(driver.getUniqueId()); - addByUniqueId(cachedDriver); - } - cachedDriver.setAttributes(driver.getAttributes()); - } - - @Override - protected void removeCachedItem(long driverId) { - Driver cachedDriver = getById(driverId); - if (cachedDriver != null) { - String driverUniqueId = cachedDriver.getUniqueId(); - super.removeCachedItem(driverId); - removeByUniqueId(driverUniqueId); - } - } - - public Driver getDriverByUniqueId(String uniqueId) { - try { - readLock(); - return driversByUniqueId.get(uniqueId); - } finally { - readUnlock(); - } - } -} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 544faf697..47941d681 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -20,7 +20,6 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Driver; import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.ManagedUser; @@ -360,7 +359,6 @@ public class PermissionsManager { if (Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshUserItems(); } - Context.getDriversManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); } @@ -370,7 +368,6 @@ public class PermissionsManager { if (Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshExtendedPermissions(); } - Context.getDriversManager().refreshExtendedPermissions(); } public void refreshPermissions(Permission permission) { @@ -383,8 +380,6 @@ public class PermissionsManager { usersManager.refreshUserItems(); } else if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshUserItems(); - } else if (permission.getPropertyClass().equals(Driver.class)) { - Context.getDriversManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); @@ -392,8 +387,6 @@ public class PermissionsManager { } else if (permission.getOwnerClass().equals(Device.class) || permission.getOwnerClass().equals(Group.class)) { if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Driver.class)) { - Context.getDriversManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshExtendedPermissions(); diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index c3e37c9e9..be90761b1 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -17,7 +17,6 @@ package org.traccar.notification; import org.apache.velocity.VelocityContext; -import org.traccar.Context; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -55,7 +54,7 @@ public final class NotificationFormatter { } String driverUniqueId = event.getString(Position.KEY_DRIVER_UNIQUE_ID); if (driverUniqueId != null) { - velocityContext.put("driver", Context.getDriversManager().getDriverByUniqueId(driverUniqueId)); + velocityContext.put("driver", cacheManager.findDriverByUniqueId(device.getId(), driverUniqueId)); } return TextTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 8dedb9a24..58dc71d2d 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -35,10 +35,20 @@ import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class StopsReportProvider { + private final Storage storage; + + @Inject + public StopsReportProvider(Storage storage) { + this.storage = storage; + } + private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); @@ -47,7 +57,7 @@ public class StopsReportProvider { DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); return ReportUtils.detectTripsAndStops( - identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), + storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), Context.getTripsConfig(), ignoreOdometer, StopReportItem.class); } diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 6aff08a1d..5ff31dbe2 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -34,10 +34,20 @@ import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class TripsReportProvider { + private final Storage storage; + + @Inject + public TripsReportProvider(Storage storage) { + this.storage = storage; + } + private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); @@ -46,7 +56,7 @@ public class TripsReportProvider { DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); return ReportUtils.detectTripsAndStops( - identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), + storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), Context.getTripsConfig(), ignoreOdometer, TripReportItem.class); } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index b56b58a58..4bcb54899 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -146,9 +146,11 @@ public final class ReportUtils { return null; } - public static String findDriverName(String driverUniqueId) { - if (driverUniqueId != null && Context.getDriversManager() != null) { - Driver driver = Context.getDriversManager().getDriverByUniqueId(driverUniqueId); + public static String findDriverName(Storage storage, String driverUniqueId) throws StorageException { + if (driverUniqueId != null) { + Driver driver = storage.getObject(Driver.class, new Request( + new Columns.All(), + new Condition.Equals("uniqueId", "uniqueId", driverUniqueId))); if (driver != null) { return driver.getName(); } @@ -186,8 +188,8 @@ public final class ReportUtils { } private static TripReportItem calculateTrip( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer) { + Storage storage, IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer) throws StorageException { Position startTrip = positions.get(startIndex); Position endTrip = positions.get(endIndex); @@ -238,7 +240,7 @@ public final class ReportUtils { trip.setSpentFuel(calculateFuel(startTrip, endTrip)); trip.setDriverUniqueId(findDriver(startTrip, endTrip)); - trip.setDriverName(findDriverName(trip.getDriverUniqueId())); + trip.setDriverName(findDriverName(storage, trip.getDriverUniqueId())); if (!ignoreOdometer && startTrip.getDouble(Position.KEY_ODOMETER) != 0 @@ -303,11 +305,11 @@ public final class ReportUtils { } private static T calculateTripOrStop( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) { + Storage storage, IdentityManager identityManager, ArrayList positions, + int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) throws StorageException { if (reportClass.equals(TripReportItem.class)) { - return (T) calculateTrip(identityManager, positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateTrip(storage, identityManager, positions, startIndex, endIndex, ignoreOdometer); } else { return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); } @@ -334,9 +336,9 @@ public final class ReportUtils { } public static Collection detectTripsAndStops( - IdentityManager identityManager, DeviceManager deviceManager, + Storage storage, IdentityManager identityManager, DeviceManager deviceManager, Collection positionCollection, - TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) { + TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) throws StorageException { Collection result = new ArrayList<>(); @@ -369,13 +371,13 @@ public final class ReportUtils { } if (startEventIndex != -1 && startNoEventIndex != -1 && event != null && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop(identityManager, positions, + result.add(calculateTripOrStop(storage, identityManager, positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); startEventIndex = -1; } } if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - result.add(calculateTripOrStop(identityManager, positions, + result.add(calculateTripOrStop(storage, identityManager, positions, startEventIndex, startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, ignoreOdometer, reportClass)); } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 102a31ecd..6ea0f252d 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -105,6 +105,13 @@ public class CacheManager { } } + public Driver findDriverByUniqueId(long deviceId, String driverUniqueId) { + return getDeviceObjects(deviceId, Driver.class).stream() + .filter(driver -> driver.getUniqueId().equals(driverUniqueId)) + .findFirst() + .orElse(null); + } + public void addDevice(long deviceId) throws StorageException { try { lock.writeLock().lock(); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index e947a9afa..9b287a0fd 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -9,6 +9,7 @@ import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.TripReportItem; import org.traccar.reports.common.TripsConfig; +import org.traccar.storage.Storage; import java.text.DateFormat; import java.text.ParseException; @@ -79,7 +80,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectTripsSimple() throws ParseException { + public void testDetectTripsSimple() throws Exception { List data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), @@ -94,7 +95,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -109,7 +110,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -131,7 +132,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectTripsSimpleWithIgnition() throws ParseException { + public void testDetectTripsSimpleWithIgnition() throws Exception { List data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), @@ -148,7 +149,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -163,7 +164,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -178,7 +179,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(3000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -200,7 +201,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectTripsWithFluctuation() throws ParseException { + public void testDetectTripsWithFluctuation() throws Exception { List data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), @@ -219,7 +220,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -234,7 +235,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7000, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -256,7 +257,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectStopsOnly() throws ParseException { + public void testDetectStopsOnly() throws Exception { Collection data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), @@ -269,7 +270,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -283,7 +284,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectStopsWithTripCut() throws ParseException { + public void testDetectStopsWithTripCut() throws Exception { Collection data = Arrays.asList( position("2016-01-01 00:00:00.000", 0, 0), @@ -296,7 +297,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -310,7 +311,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectStopsStartedFromTrip() throws ParseException { + public void testDetectStopsStartedFromTrip() throws Exception { Collection data = Arrays.asList( position("2016-01-01 00:00:00.000", 2, 0), @@ -323,7 +324,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -337,7 +338,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectStopsMoving() throws ParseException { + public void testDetectStopsMoving() throws Exception { Collection data = Arrays.asList( position("2016-01-01 00:00:00.000", 5, 0), @@ -350,7 +351,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); Collection result = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -358,7 +359,7 @@ public class ReportUtilsTest extends BaseTest { } @Test - public void testDetectTripAndStopByGap() throws ParseException { + public void testDetectTripAndStopByGap() throws Exception { Collection data = Arrays.asList( position("2016-01-01 00:00:00.000", 7, 100), @@ -373,7 +374,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); Collection trips = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -388,7 +389,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(600, itemTrip.getDistance(), 0.01); Collection stops = ReportUtils.detectTripsAndStops( - mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 104281f161f622df8fca0c65a5b9969ceb03c46f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 18:04:24 -0700 Subject: Extract user utils from reports --- build.gradle | 2 +- src/main/java/org/traccar/Main.java | 3 +- .../org/traccar/api/resource/PasswordResource.java | 3 +- .../traccar/api/security/PermissionsService.java | 2 + .../org/traccar/database/PermissionsManager.java | 12 ----- src/main/java/org/traccar/helper/UserUtil.java | 57 ++++++++++++++++++++++ .../notification/NotificationFormatter.java | 12 +++-- .../notification/TextTemplateFormatter.java | 9 ++-- .../org/traccar/reports/EventsReportProvider.java | 8 ++- .../org/traccar/reports/RouteReportProvider.java | 13 ++++- .../org/traccar/reports/StopsReportProvider.java | 8 ++- .../org/traccar/reports/SummaryReportProvider.java | 19 ++++++-- .../org/traccar/reports/TripsReportProvider.java | 8 ++- .../org/traccar/reports/common/ReportUtils.java | 30 +++--------- .../org/traccar/session/cache/CacheManager.java | 36 +++++++++++--- src/main/java/org/traccar/web/WebServer.java | 3 ++ 16 files changed, 162 insertions(+), 63 deletions(-) create mode 100644 src/main/java/org/traccar/helper/UserUtil.java diff --git a/build.gradle b/build.gradle index de8c86712..8c196043a 100644 --- a/build.gradle +++ b/build.gradle @@ -49,7 +49,7 @@ dependencies { implementation "io.netty:netty-all:4.1.66.Final" implementation "org.slf4j:slf4j-jdk14:2.0.0-alpha6" implementation "com.google.inject:guice:$guiceVersion" - implementation "com.google.inject.extensions:guice-assistedinject:$guiceVersion" + implementation "com.google.inject.extensions:guice-servlet:$guiceVersion" implementation "org.owasp.encoder:encoder:1.2.3" implementation "org.glassfish:javax.json:1.1.4" implementation "org.eclipse.jetty:jetty-server:$jettyVersion" diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index db9892bb9..b14f22a00 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -17,6 +17,7 @@ package org.traccar; import com.google.inject.Guice; import com.google.inject.Injector; +import com.google.inject.servlet.ServletModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.schedule.ScheduleManager; @@ -111,7 +112,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule()); + injector = Guice.createInjector(new MainModule(), new ServletModule()); Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index ed7131718..91d994153 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -51,7 +51,8 @@ public class PasswordResource extends BaseResource { String token = UUID.randomUUID().toString().replaceAll("-", ""); user.set(PASSWORD_RESET_TOKEN, token); Context.getUsersManager().updateItem(user); - VelocityContext velocityContext = TextTemplateFormatter.prepareContext(null); + VelocityContext velocityContext = TextTemplateFormatter.prepareContext( + permissionsService.getServer(), user); velocityContext.put("token", token); NotificationMessage fullMessage = TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 9ec3b43c1..c70414b2a 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -15,6 +15,7 @@ */ package org.traccar.api.security; +import com.google.inject.servlet.RequestScoped; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Command; @@ -34,6 +35,7 @@ import org.traccar.storage.query.Request; import javax.inject.Inject; +@RequestScoped public class PermissionsService { private final Storage storage; diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 47941d681..e8f2380a2 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -412,16 +412,4 @@ public class PermissionsManager { return null; } - public Object lookupAttribute(long userId, String key, Object defaultValue) { - Object preference; - Object serverPreference = server.getAttributes().get(key); - Object userPreference = getUser(userId).getAttributes().get(key); - if (server.getForceSettings()) { - preference = serverPreference != null ? serverPreference : userPreference; - } else { - preference = userPreference != null ? userPreference : serverPreference; - } - return preference != null ? preference : defaultValue; - } - } diff --git a/src/main/java/org/traccar/helper/UserUtil.java b/src/main/java/org/traccar/helper/UserUtil.java new file mode 100644 index 000000000..6050ad349 --- /dev/null +++ b/src/main/java/org/traccar/helper/UserUtil.java @@ -0,0 +1,57 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper; + +import org.traccar.model.Server; +import org.traccar.model.User; + +import java.util.TimeZone; + +public final class UserUtil { + + private UserUtil() { + } + + public static String getDistanceUnit(Server server, User user) { + return lookupStringAttribute(server, user, "distanceUnit", "km"); + } + + public static String getSpeedUnit(Server server, User user) { + return lookupStringAttribute(server, user, "speedUnit", "kn"); + } + + public static String getVolumeUnit(Server server, User user) { + return lookupStringAttribute(server, user, "volumeUnit", "ltr"); + } + + public static TimeZone getTimezone(Server server, User user) { + String timezone = lookupStringAttribute(server, user, "timezone", null); + return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); + } + + private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { + String preference; + String serverPreference = server.getString(key); + String userPreference = user.getString(key); + if (server.getForceSettings()) { + preference = serverPreference != null ? serverPreference : userPreference; + } else { + preference = userPreference != null ? userPreference : serverPreference; + } + return preference != null ? preference : defaultValue; + } + +} diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index be90761b1..13f42a8b2 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -17,13 +17,14 @@ package org.traccar.notification; import org.apache.velocity.VelocityContext; +import org.traccar.helper.UserUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Position; +import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.reports.common.ReportUtils; import org.traccar.session.cache.CacheManager; public final class NotificationFormatter { @@ -34,17 +35,18 @@ public final class NotificationFormatter { public static NotificationMessage formatMessage( CacheManager cacheManager, User user, Event event, Position position, String templatePath) { + Server server = cacheManager.getServer(); Device device = cacheManager.getObject(Device.class, event.getDeviceId()); - VelocityContext velocityContext = TextTemplateFormatter.prepareContext(user); + VelocityContext velocityContext = TextTemplateFormatter.prepareContext(server, user); velocityContext.put("device", device); velocityContext.put("event", event); if (position != null) { velocityContext.put("position", position); - velocityContext.put("speedUnit", ReportUtils.getSpeedUnit(user.getId())); - velocityContext.put("distanceUnit", ReportUtils.getDistanceUnit(user.getId())); - velocityContext.put("volumeUnit", ReportUtils.getVolumeUnit(user.getId())); + velocityContext.put("speedUnit", UserUtil.getSpeedUnit(server, user)); + velocityContext.put("distanceUnit", UserUtil.getDistanceUnit(server, user)); + velocityContext.put("volumeUnit", UserUtil.getVolumeUnit(server, user)); } if (event.getGeofenceId() != 0) { velocityContext.put("geofence", cacheManager.getObject(Geofence.class, event.getGeofenceId())); diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 469de2d4a..06375afac 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@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,8 +23,9 @@ import org.apache.velocity.tools.generic.NumberTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.helper.UserUtil; +import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.reports.common.ReportUtils; import java.io.StringWriter; import java.nio.charset.StandardCharsets; @@ -38,13 +39,13 @@ public final class TextTemplateFormatter { private TextTemplateFormatter() { } - public static VelocityContext prepareContext(User user) { + public static VelocityContext prepareContext(Server server, User user) { VelocityContext velocityContext = new VelocityContext(); if (user != null) { velocityContext.put("user", user); - velocityContext.put("timezone", ReportUtils.getTimezone(user.getId())); + velocityContext.put("timezone", UserUtil.getTimezone(server, user)); } velocityContext.put("webUrl", Context.getVelocityEngine().getProperty("web.url")); diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 9b4a7df2b..f0c8c31b6 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -28,6 +28,7 @@ import java.util.Iterator; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -42,10 +43,12 @@ import javax.inject.Inject; public class EventsReportProvider { + private final PermissionsService permissionsService; private final Storage storage; @Inject - public EventsReportProvider(Storage storage) { + public EventsReportProvider(PermissionsService permissionsService, Storage storage) { + this.permissionsService = permissionsService; this.storage = storage; } @@ -127,7 +130,8 @@ public class EventsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesEvents); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("geofenceNames", geofenceNames); diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 4c4a41405..e20ba6885 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -26,6 +26,7 @@ import java.util.Date; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; @@ -33,8 +34,17 @@ import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class RouteReportProvider { + private final PermissionsService permissionsService; + + @Inject + public RouteReportProvider(PermissionsService permissionsService) { + this.permissionsService = permissionsService; + } + public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { ReportUtils.checkPeriodLimit(from, to); @@ -72,7 +82,8 @@ public class RouteReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesRoutes); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 58dc71d2d..8899dc42f 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -28,6 +28,7 @@ import java.util.Date; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.Main; +import org.traccar.api.security.PermissionsService; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; @@ -42,10 +43,12 @@ import javax.inject.Inject; public class StopsReportProvider { + private final PermissionsService permissionsService; private final Storage storage; @Inject - public StopsReportProvider(Storage storage) { + public StopsReportProvider(PermissionsService permissionsService, Storage storage) { + this.permissionsService = permissionsService; this.storage = storage; } @@ -98,7 +101,8 @@ public class StopsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesStops); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index a2306f3d1..c9fac4309 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -27,14 +27,25 @@ import java.util.Date; import org.jxls.util.JxlsHelper; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.UserUtil; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReportItem; import org.traccar.storage.StorageException; +import javax.inject.Inject; + public class SummaryReportProvider { + private final PermissionsService permissionsService; + + @Inject + public SummaryReportProvider(PermissionsService permissionsService) { + this.permissionsService = permissionsService; + } + private SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { SummaryReportItem result = new SummaryReportItem(); result.setDeviceId(deviceId); @@ -88,8 +99,9 @@ public class SummaryReportProvider { return result; } - private int getDay(long userId, Date date) { - Calendar calendar = Calendar.getInstance(ReportUtils.getTimezone(userId)); + private int getDay(long userId, Date date) throws StorageException { + Calendar calendar = Calendar.getInstance(UserUtil.getTimezone( + permissionsService.getServer(), permissionsService.getUser(userId))); calendar.setTime(date); return calendar.get(Calendar.DAY_OF_MONTH); } @@ -144,7 +156,8 @@ public class SummaryReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("summaries", summaries); jxlsContext.putVar("from", from); jxlsContext.putVar("to", to); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 5ff31dbe2..bcd79ab25 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -27,6 +27,7 @@ import java.util.Date; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.Main; +import org.traccar.api.security.PermissionsService; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; @@ -41,10 +42,12 @@ import javax.inject.Inject; public class TripsReportProvider { + private final PermissionsService permissionsService; private final Storage storage; @Inject - public TripsReportProvider(Storage storage) { + public TripsReportProvider(PermissionsService permissionsService, Storage storage) { + this.permissionsService = permissionsService; this.storage = storage; } @@ -96,7 +99,8 @@ public class TripsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { - org.jxls.common.Context jxlsContext = ReportUtils.initializeContext(userId); + var jxlsContext = ReportUtils.initializeContext( + permissionsService.getServer(), permissionsService.getUser(userId)); jxlsContext.putVar("devices", devicesTrips); jxlsContext.putVar("sheetNames", sheetNames); jxlsContext.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 4bcb54899..71c49f65b 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -31,7 +31,9 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.UserUtil; import org.traccar.model.BaseModel; +import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.session.DeviceState; import org.traccar.model.Driver; @@ -58,7 +60,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.TimeZone; public final class ReportUtils { @@ -81,23 +82,6 @@ public final class ReportUtils { } } - public static String getDistanceUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "distanceUnit", "km"); - } - - public static String getSpeedUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "speedUnit", "kn"); - } - - public static String getVolumeUnit(long userId) { - return (String) Context.getPermissionsManager().lookupAttribute(userId, "volumeUnit", "ltr"); - } - - public static TimeZone getTimezone(long userId) { - String timezone = (String) Context.getPermissionsManager().lookupAttribute(userId, "timezone", null); - return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); - } - public static Collection getDeviceList(Collection deviceIds, Collection groupIds) { Collection result = new LinkedHashSet<>(deviceIds); for (long groupId : groupIds) { @@ -158,15 +142,15 @@ public final class ReportUtils { return null; } - public static org.jxls.common.Context initializeContext(long userId) { + public static org.jxls.common.Context initializeContext(Server server, User user) { org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext(); - jxlsContext.putVar("distanceUnit", getDistanceUnit(userId)); - jxlsContext.putVar("speedUnit", getSpeedUnit(userId)); - jxlsContext.putVar("volumeUnit", getVolumeUnit(userId)); + jxlsContext.putVar("distanceUnit", UserUtil.getDistanceUnit(server, user)); + jxlsContext.putVar("speedUnit", UserUtil.getSpeedUnit(server, user)); + jxlsContext.putVar("volumeUnit", UserUtil.getVolumeUnit(server, user)); jxlsContext.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); jxlsContext.putVar("dateTool", new DateTool()); jxlsContext.putVar("numberTool", new NumberTool()); - jxlsContext.putVar("timezone", getTimezone(userId)); + jxlsContext.putVar("timezone", UserUtil.getTimezone(server, user)); jxlsContext.putVar("locale", Locale.getDefault()); jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); return jxlsContext; diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 6ea0f252d..586237655 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -23,6 +23,7 @@ import org.traccar.model.Geofence; import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.Position; +import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -57,12 +58,14 @@ public class CacheManager { private final Map deviceCache = new HashMap<>(); private final Map, List>> deviceLinks = new HashMap<>(); + private Server server; private final Map devicePositions = new HashMap<>(); private final Map> notificationUsers = new HashMap<>(); @Inject public CacheManager(Storage storage) throws StorageException { this.storage = storage; + invalidateServer(); invalidateUsers(); } @@ -96,6 +99,15 @@ public class CacheManager { } } + public Server getServer() { + try { + lock.readLock().lock(); + return server; + } finally { + lock.readLock().unlock(); + } + } + public List getNotificationUsers(long notificationId) { try { lock.readLock().lock(); @@ -154,6 +166,10 @@ public class CacheManager { invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); } + private void invalidateServer() throws StorageException { + server = storage.getObject(Server.class, new Request(new Columns.All())); + } + private void invalidateUsers() throws StorageException { Map users = new HashMap<>(); storage.getObjects(User.class, new Request(new Columns.All())) @@ -220,21 +236,29 @@ public class CacheManager { } private void unsafeInvalidate(CacheKey[] keys) throws StorageException { + boolean invalidateServer = false; boolean invalidateUsers = false; Set linkedDevices = new HashSet<>(); for (var key : keys) { - if (key.classIs(User.class) || key.classIs(Notification.class)) { - invalidateUsers = true; + if (key.classIs(Server.class)) { + invalidateServer = true; + } else { + if (key.classIs(User.class) || key.classIs(Notification.class)) { + invalidateUsers = true; + } + deviceCache.computeIfPresent(key, (k, value) -> { + linkedDevices.addAll(value.getReferences()); + return value; + }); } - deviceCache.computeIfPresent(key, (k, value) -> { - linkedDevices.addAll(value.getReferences()); - return value; - }); } for (long deviceId : linkedDevices) { unsafeRemoveDevice(deviceId); unsafeAddDevice(deviceId); } + if (invalidateServer) { + invalidateServer(); + } if (invalidateUsers) { invalidateUsers(); } diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 06676fb41..f1ee8fcb2 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -15,6 +15,7 @@ */ package org.traccar.web; +import com.google.inject.servlet.GuiceFilter; import org.eclipse.jetty.http.HttpCookie; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; @@ -164,6 +165,8 @@ public class WebServer implements LifecycleObject { } private void initApi(Config config, ServletContextHandler servletHandler) { + servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); + servletHandler.addServlet(new ServletHolder(new AsyncSocketServlet()), "/api/socket"); JettyWebSocketServletContainerInitializer.configure(servletHandler, null); -- cgit v1.2.3 From 5890e03199142f041dc19160329a740b4d01450d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 7 Jun 2022 19:23:16 -0700 Subject: Fix last position requests (fix #4863) --- .../java/org/traccar/api/resource/AttributeResource.java | 16 +++------------- src/main/java/org/traccar/database/CommandsManager.java | 2 +- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index fdd0d4f6f..ab7e43add 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -53,22 +53,12 @@ public class AttributeResource extends ExtendedObjectResource { permissionsService.checkAdmin(getUserId()); permissionsService.checkPermission(Device.class, getUserId(), deviceId); - Device device = storage.getObject(Device.class, new Request( + Position position = storage.getObject(Position.class, new Request( new Columns.All(), - new Condition.Equals("id", "id", deviceId))); - if (device == null) { - throw new IllegalArgumentException("Device not found"); - } - - Position last = storage.getObject(Position.class, new Request( - new Columns.All(), - new Condition.Equals("id", "id", device.getPositionId()))); - if (last == null) { - throw new IllegalArgumentException("Device has no last position"); - } + new Condition.LatestPositions(deviceId))); Object result = new ComputedAttributesHandler(Context.getConfig(), Context.getIdentityManager(), null) - .computeAttribute(entity, last); + .computeAttribute(entity, position); if (result != null) { switch (entity.getType()) { case "number": diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 8dd2ba8b7..2967b8abd 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -72,7 +72,7 @@ public class CommandsManager { long deviceId = command.getDeviceId(); if (command.getTextChannel()) { Device device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId))); + new Columns.Include("positionId", "phone"), new Condition.Equals("id", "id", deviceId))); Position position = storage.getObject(Position.class, new Request( new Columns.All(), new Condition.Equals("id", "id", device.getPositionId()))); if (position != null) { -- cgit v1.2.3 From cd229daa23cfc43ad5056c45c4aaecefdbbf826c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 8 Jun 2022 07:52:59 -0700 Subject: Improve cache invalidation --- .../java/org/traccar/api/BaseObjectResource.java | 8 ++++ .../traccar/api/resource/PermissionsResource.java | 9 ++++ .../handler/events/MaintenanceEventHandler.java | 3 +- .../org/traccar/session/cache/CacheManager.java | 50 ++++++++++++---------- .../java/org/traccar/session/cache/CacheValue.java | 6 ++- 5 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index d6401dc42..c033fbb62 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -27,11 +27,13 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.User; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.inject.Inject; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -42,6 +44,9 @@ import javax.ws.rs.core.Response; public abstract class BaseObjectResource extends BaseResource { + @Inject + private CacheManager cacheManager; + protected final Class baseClass; public BaseObjectResource(Class baseClass) { @@ -75,6 +80,7 @@ public abstract class BaseObjectResource extends BaseResour LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); + cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); if (manager instanceof SimpleObjectManager) { @@ -100,6 +106,7 @@ public abstract class BaseObjectResource extends BaseResour new Columns.Exclude("id"), new Condition.Equals("id", "id"))); } + cacheManager.updateOrInvalidate(baseClass, entity.getId()); LogAction.edit(getUserId(), entity); @@ -128,6 +135,7 @@ public abstract class BaseObjectResource extends BaseResour } else { storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); } + cacheManager.updateOrInvalidate(baseClass, id); LogAction.remove(getUserId(), baseClass, id); diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 484c61e66..a4db6754c 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -20,8 +20,10 @@ import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Permission; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.POST; @@ -40,6 +42,9 @@ import java.util.Set; @Consumes(MediaType.APPLICATION_JSON) public class PermissionsResource extends BaseResource { + @Inject + private CacheManager cacheManager; + private void checkPermission(Permission permission, boolean link) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); @@ -67,6 +72,8 @@ public class PermissionsResource extends BaseResource { checkPermission(permission, true); Context.getDataManager().linkObject(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId(), true); + cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), + permission.getPropertyClass(), permission.getPropertyId()); LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } @@ -91,6 +98,8 @@ public class PermissionsResource extends BaseResource { checkPermission(permission, false); Context.getDataManager().linkObject(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId(), false); + cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), + permission.getPropertyClass(), permission.getPropertyId()); LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index be3e9bf8d..f85aab043 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.Map; import io.netty.channel.ChannelHandler; +import org.traccar.Context; import org.traccar.model.Event; import org.traccar.model.Maintenance; import org.traccar.model.Position; @@ -39,7 +40,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { @Override protected Map analyzePosition(Position position) { - Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) < 0) { return null; } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 586237655..8e1737441 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -20,9 +20,9 @@ import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; +import org.traccar.model.GroupedModel; import org.traccar.model.Maintenance; import org.traccar.model.Notification; -import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; @@ -59,7 +59,6 @@ public class CacheManager { private final Map, List>> deviceLinks = new HashMap<>(); private Server server; - private final Map devicePositions = new HashMap<>(); private final Map> notificationUsers = new HashMap<>(); @Inject @@ -90,15 +89,6 @@ public class CacheManager { } } - public Position getPosition(long deviceId) { - try { - lock.readLock().lock(); - return devicePositions.get(deviceId); - } finally { - lock.readLock().unlock(); - } - } - public Server getServer() { try { lock.readLock().lock(); @@ -146,18 +136,34 @@ public class CacheManager { } } - public void updatePosition(Position position) { - try { - lock.writeLock().lock(); - devicePositions.put(position.getDeviceId(), position); - } finally { - lock.writeLock().unlock(); + public void updateOrInvalidate(Class clazz, long id) throws StorageException { + boolean invalidate = false; + var before = getObject(clazz, id); + var after = storage.getObject(clazz, new Request( + new Columns.All(), new Condition.Equals("id", "id", id))); + if (before == null) { + return; + } else if (after == null) { + invalidate = true; + } else if (clazz.isInstance(GroupedModel.class)) { + if (((GroupedModel) before).getGroupId() != ((GroupedModel) after).getGroupId()) { + invalidate = true; + } + } + if (invalidate) { + invalidate(new CacheKey(clazz, id)); + } else { + try { + lock.writeLock().lock(); + var cacheValue = deviceCache.get(new CacheKey(clazz, id)); + if (cacheValue != null) { + cacheValue.setValue(after); + } + // TODO if device, also need to update geofences + } finally { + lock.writeLock().unlock(); + } } - } - - public void invalidate( - Class clazz, long id) throws StorageException { - invalidate(new CacheKey(clazz, id)); } public void invalidate( diff --git a/src/main/java/org/traccar/session/cache/CacheValue.java b/src/main/java/org/traccar/session/cache/CacheValue.java index 9e955dfe5..1f0383ce5 100644 --- a/src/main/java/org/traccar/session/cache/CacheValue.java +++ b/src/main/java/org/traccar/session/cache/CacheValue.java @@ -22,7 +22,7 @@ import java.util.Set; class CacheValue { - private final BaseModel value; + private BaseModel value; private final Set references = new HashSet<>(); CacheValue(BaseModel value) { @@ -42,6 +42,10 @@ class CacheValue { return (T) value; } + public void setValue(BaseModel value) { + this.value = value; + } + public Set getReferences() { return references; } -- cgit v1.2.3 From 65d3654dcca878cfd839e40c0dd020da199be09e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 8 Jun 2022 08:14:20 -0700 Subject: More cache improvements --- .../java/org/traccar/api/BaseObjectResource.java | 4 +-- .../org/traccar/session/cache/CacheManager.java | 35 +++++++++++++--------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index c033fbb62..eb1db5e89 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -106,7 +106,7 @@ public abstract class BaseObjectResource extends BaseResour new Columns.Exclude("id"), new Condition.Equals("id", "id"))); } - cacheManager.updateOrInvalidate(baseClass, entity.getId()); + cacheManager.updateOrInvalidate(entity); LogAction.edit(getUserId(), entity); @@ -135,7 +135,7 @@ public abstract class BaseObjectResource extends BaseResour } else { storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); } - cacheManager.updateOrInvalidate(baseClass, id); + cacheManager.invalidate(baseClass, id); LogAction.remove(getUserId(), baseClass, id); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 8e1737441..a934431be 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -136,36 +136,43 @@ public class CacheManager { } } - public void updateOrInvalidate(Class clazz, long id) throws StorageException { - boolean invalidate = false; - var before = getObject(clazz, id); - var after = storage.getObject(clazz, new Request( + public void updateOrInvalidate(Class clazz, long id) throws StorageException { + var object = storage.getObject(clazz, new Request( new Columns.All(), new Condition.Equals("id", "id", id))); + if (object != null) { + updateOrInvalidate(object); + } else { + invalidate(clazz, id); + } + } + + public void updateOrInvalidate(T object) throws StorageException { + boolean invalidate = false; + var before = getObject(object.getClass(), object.getId()); if (before == null) { return; - } else if (after == null) { - invalidate = true; - } else if (clazz.isInstance(GroupedModel.class)) { - if (((GroupedModel) before).getGroupId() != ((GroupedModel) after).getGroupId()) { + } else if (object instanceof GroupedModel) { + if (((GroupedModel) before).getGroupId() != ((GroupedModel) object).getGroupId()) { invalidate = true; } } if (invalidate) { - invalidate(new CacheKey(clazz, id)); + invalidate(object.getClass(), object.getId()); } else { + // TODO if device, also need to update geofences try { lock.writeLock().lock(); - var cacheValue = deviceCache.get(new CacheKey(clazz, id)); - if (cacheValue != null) { - cacheValue.setValue(after); - } - // TODO if device, also need to update geofences + deviceCache.get(new CacheKey(object.getClass(), object.getId())).setValue(object); } finally { lock.writeLock().unlock(); } } } + public void invalidate(Class clazz, long id) throws StorageException { + invalidate(new CacheKey(clazz, id)); + } + public void invalidate( Class clazz1, long id1, Class clazz2, long id2) throws StorageException { -- cgit v1.2.3 From c4ff983ffe9a03a57d3ab0596abe8bce08c1ae2e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 06:39:10 -0700 Subject: Add position cache --- src/main/java/org/traccar/MainEventHandler.java | 2 ++ .../java/org/traccar/database/DeviceManager.java | 3 ++ .../org/traccar/session/cache/CacheManager.java | 33 ++++++++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index f04307fdb..bb84a09d2 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -28,6 +28,7 @@ import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.helper.NetworkUtil; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -60,6 +61,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { Position position = (Position) msg; try { Context.getDeviceManager().updateLatestPosition(position); + Main.getInjector().getInstance(CacheManager.class).updatePosition(position); } catch (StorageException error) { LOGGER.warn("Failed to update device", error); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index b1ea0b8b7..0bac8f642 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicLong; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.Main; import org.traccar.config.Config; import org.traccar.Context; import org.traccar.config.Keys; @@ -36,6 +37,7 @@ import org.traccar.model.DeviceAccumulators; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; public class DeviceManager extends BaseObjectManager implements IdentityManager { @@ -406,6 +408,7 @@ public class DeviceManager extends BaseObjectManager implements Identity } getDataManager().addObject(last); updateLatestPosition(last); + Main.getInjector().getInstance(CacheManager.class).updatePosition(last); } else { throw new IllegalArgumentException(); } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index a934431be..4b42ea4e5 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -23,6 +23,7 @@ import org.traccar.model.Geofence; import org.traccar.model.GroupedModel; import org.traccar.model.Maintenance; import org.traccar.model.Notification; +import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; @@ -57,6 +58,7 @@ public class CacheManager { private final Map deviceCache = new HashMap<>(); private final Map, List>> deviceLinks = new HashMap<>(); + private final Map devicePositions = new HashMap<>(); private Server server; private final Map> notificationUsers = new HashMap<>(); @@ -89,6 +91,15 @@ public class CacheManager { } } + public Position getPosition(long deviceId) { + try { + lock.readLock().lock(); + return devicePositions.get(deviceId); + } finally { + lock.readLock().unlock(); + } + } + public Server getServer() { try { lock.readLock().lock(); @@ -136,6 +147,17 @@ public class CacheManager { } } + public void updatePosition(Position position) { + try { + lock.writeLock().lock(); + if (deviceLinks.containsKey(position.getDeviceId())) { + devicePositions.put(position.getDeviceId(), position); + } + } finally { + lock.writeLock().unlock(); + } + } + public void updateOrInvalidate(Class clazz, long id) throws StorageException { var object = storage.getObject(clazz, new Request( new Columns.All(), new Condition.Equals("id", "id", id))); @@ -201,8 +223,9 @@ public class CacheManager { private void unsafeAddDevice(long deviceId) throws StorageException { Map, List> links = new HashMap<>(); - addObject(deviceId, storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId)))); + Device device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId))); + addObject(deviceId, device); for (Class clazz : CLASSES) { var objects = storage.getObjects(clazz, new Request( @@ -226,6 +249,11 @@ public class CacheManager { } deviceLinks.put(deviceId, links); + + if (device.getPositionId() > 0) { + devicePositions.put(deviceId, storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); + } } private void unsafeRemoveDevice(long deviceId) { @@ -237,6 +265,7 @@ public class CacheManager { return value.getReferences().size() > 0 ? value : null; }); })); + devicePositions.remove(deviceId); } private void invalidate(CacheKey... keys) throws StorageException { -- cgit v1.2.3 From 12fe28bebbdbc61214363a9c7b51bd300ed62c15 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 07:00:20 -0700 Subject: Remove geofence manager --- src/main/java/org/traccar/Context.java | 11 ---- src/main/java/org/traccar/MainModule.java | 6 -- .../java/org/traccar/api/BaseObjectResource.java | 1 - .../java/org/traccar/database/DeviceManager.java | 6 -- .../java/org/traccar/database/GeofenceManager.java | 66 ---------------------- .../org/traccar/database/PermissionsManager.java | 13 +---- .../handler/events/GeofenceEventHandler.java | 34 +++++------ .../handler/events/OverspeedEventHandler.java | 12 ++-- src/main/java/org/traccar/helper/UserUtil.java | 57 ------------------- .../org/traccar/helper/model/GeofenceUtil.java | 40 +++++++++++++ .../org/traccar/helper/model/PositionUtil.java | 31 ++++++++++ .../java/org/traccar/helper/model/UserUtil.java | 57 +++++++++++++++++++ .../notification/NotificationFormatter.java | 2 +- .../notification/TextTemplateFormatter.java | 2 +- .../org/traccar/reports/SummaryReportProvider.java | 2 +- .../org/traccar/reports/common/ReportUtils.java | 2 +- .../org/traccar/session/cache/CacheManager.java | 15 ++++- 17 files changed, 167 insertions(+), 190 deletions(-) delete mode 100644 src/main/java/org/traccar/database/GeofenceManager.java delete mode 100644 src/main/java/org/traccar/helper/UserUtil.java create mode 100644 src/main/java/org/traccar/helper/model/GeofenceUtil.java create mode 100644 src/main/java/org/traccar/helper/model/PositionUtil.java create mode 100644 src/main/java/org/traccar/helper/model/UserUtil.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 899f8ea54..dcbe6c811 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -26,7 +26,6 @@ import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.GeofenceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; import org.traccar.database.MailManager; @@ -38,7 +37,6 @@ import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Notification; import org.traccar.model.User; @@ -140,12 +138,6 @@ public final class Context { return broadcastService; } - private static GeofenceManager geofenceManager; - - public static GeofenceManager getGeofenceManager() { - return geofenceManager; - } - private static NotificationManager notificationManager; public static NotificationManager getNotificationManager() { @@ -273,7 +265,6 @@ public final class Context { private static void initEventsModule() { - geofenceManager = new GeofenceManager(dataManager); notificationManager = new NotificationManager(dataManager, Main.getInjector().getInstance(CacheManager.class)); notificatorManager = new NotificatorManager(); Properties velocityProperties = new Properties(); @@ -312,8 +303,6 @@ public final class Context { return (BaseObjectManager) groupsManager; } else if (clazz.equals(User.class)) { return (BaseObjectManager) usersManager; - } else if (clazz.equals(Geofence.class)) { - return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Notification.class)) { return (BaseObjectManager) notificationManager; } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index b757b99a7..bb264cff3 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -27,7 +27,6 @@ import org.traccar.database.LdapProvider; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.GeofenceManager; import org.traccar.database.IdentityManager; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; @@ -119,11 +118,6 @@ public class MainModule extends AbstractModule { return Context.getDeviceManager(); } - @Provides - public static GeofenceManager provideGeofenceManager() { - return Context.getGeofenceManager(); - } - @Provides public static SmsManager provideSmsManager() { return Context.getSmsManager(); diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index eb1db5e89..cc930c591 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -151,7 +151,6 @@ public abstract class BaseObjectResource extends BaseResour Context.getPermissionsManager().refreshAllExtendedPermissions(); } } else if (baseClass.equals(Calendar.class)) { - Context.getGeofenceManager().refreshItems(); Context.getNotificationManager().refreshItems(); } return Response.noContent().build(); diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 0bac8f642..20f179f2e 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -218,12 +218,6 @@ public class DeviceManager extends BaseObjectManager implements Identity protected void addNewItem(Device device) { super.addNewItem(device); addByUniqueId(device); - if (Context.getGeofenceManager() != null) { - Position lastPosition = getLastPosition(device.getId()); - if (lastPosition != null) { - device.setGeofenceIds(Context.getGeofenceManager().getCurrentDeviceGeofences(lastPosition)); - } - } } @Override diff --git a/src/main/java/org/traccar/database/GeofenceManager.java b/src/main/java/org/traccar/database/GeofenceManager.java deleted file mode 100644 index a32847cf9..000000000 --- a/src/main/java/org/traccar/database/GeofenceManager.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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.database; - -import java.util.ArrayList; -import java.util.List; - -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Geofence; -import org.traccar.model.Position; - -public class GeofenceManager extends ExtendedObjectManager { - - public GeofenceManager(DataManager dataManager) { - super(dataManager, Geofence.class); - } - - @Override - public final void refreshExtendedPermissions() { - super.refreshExtendedPermissions(); - recalculateDevicesGeofences(); - } - - public List getCurrentDeviceGeofences(Position position) { - List result = new ArrayList<>(); - for (long geofenceId : getAllDeviceItems(position.getDeviceId())) { - Geofence geofence = getById(geofenceId); - if (geofence != null && geofence.getGeometry() - .containsPoint(position.getLatitude(), position.getLongitude())) { - result.add(geofenceId); - } - } - return result; - } - - public void recalculateDevicesGeofences() { - for (Device device : Context.getDeviceManager().getAllDevices()) { - List deviceGeofenceIds = device.getGeofenceIds(); - if (deviceGeofenceIds == null) { - deviceGeofenceIds = new ArrayList<>(); - } else { - deviceGeofenceIds.clear(); - } - Position lastPosition = Context.getIdentityManager().getLastPosition(device.getId()); - if (lastPosition != null && getAllDeviceItems(device.getId()) != null) { - deviceGeofenceIds.addAll(getCurrentDeviceGeofences(lastPosition)); - } - device.setGeofenceIds(deviceGeofenceIds); - } - } - -} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index e8f2380a2..3c74c0049 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -20,7 +20,6 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.ManagedUser; import org.traccar.model.Notification; @@ -356,18 +355,12 @@ public class PermissionsManager { } public void refreshAllUsersPermissions() { - if (Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshUserItems(); - } if (Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); } } public void refreshAllExtendedPermissions() { - if (Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshExtendedPermissions(); - } } public void refreshPermissions(Permission permission) { @@ -378,16 +371,12 @@ public class PermissionsManager { refreshAllExtendedPermissions(); } else if (permission.getPropertyClass().equals(ManagedUser.class)) { usersManager.refreshUserItems(); - } else if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshUserItems(); } } else if (permission.getOwnerClass().equals(Device.class) || permission.getOwnerClass().equals(Group.class)) { - if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshExtendedPermissions(); - } else if (permission.getPropertyClass().equals(Notification.class) + if (permission.getPropertyClass().equals(Notification.class) && Context.getNotificationManager() != null) { Context.getNotificationManager().refreshExtendedPermissions(); } diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 17e240f68..724f8f0d0 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -15,52 +15,46 @@ */ package org.traccar.handler.events; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import io.netty.channel.ChannelHandler; -import org.traccar.session.ConnectionManager; -import org.traccar.database.GeofenceManager; -import org.traccar.database.IdentityManager; +import org.traccar.helper.model.GeofenceUtil; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Event; +import org.traccar.model.Geofence; import org.traccar.model.Position; +import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { private final CacheManager cacheManager; - private final IdentityManager identityManager; - private final GeofenceManager geofenceManager; private final ConnectionManager connectionManager; @Inject - public GeofenceEventHandler( - CacheManager cacheManager, IdentityManager identityManager, GeofenceManager geofenceManager, - ConnectionManager connectionManager) { + public GeofenceEventHandler(CacheManager cacheManager, ConnectionManager connectionManager) { this.cacheManager = cacheManager; - this.identityManager = identityManager; - this.geofenceManager = geofenceManager; this.connectionManager = connectionManager; } @Override protected Map analyzePosition(Position position) { - Device device = identityManager.getById(position.getDeviceId()); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); if (device == null) { return null; } - if (!identityManager.isLatestPosition(position) || !position.getValid()) { + if (!PositionUtil.isLatest(cacheManager, position) || !position.getValid()) { return null; } - List currentGeofences = geofenceManager.getCurrentDeviceGeofences(position); + List currentGeofences = GeofenceUtil.getCurrentGeofences(cacheManager, position); List oldGeofences = new ArrayList<>(); if (device.getGeofenceIds() != null) { oldGeofences.addAll(device.getGeofenceIds()); @@ -76,7 +70,7 @@ public class GeofenceEventHandler extends BaseEventHandler { Map events = new HashMap<>(); for (long geofenceId : oldGeofences) { - long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + long calendarId = cacheManager.getObject(Geofence.class, geofenceId).getCalendarId(); Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position); @@ -85,7 +79,7 @@ public class GeofenceEventHandler extends BaseEventHandler { } } for (long geofenceId : newGeofences) { - long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + long calendarId = cacheManager.getObject(Geofence.class, geofenceId).getCalendarId(); Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position); diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 84d80e55f..45bb13be5 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -23,12 +23,12 @@ import io.netty.channel.ChannelHandler; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceManager; -import org.traccar.database.GeofenceManager; import org.traccar.model.Device; import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @@ -39,16 +39,16 @@ public class OverspeedEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit"; private final DeviceManager deviceManager; - private final GeofenceManager geofenceManager; + private final CacheManager cacheManager; private final boolean notRepeat; private final long minimalDuration; private final boolean preferLowest; @Inject - public OverspeedEventHandler(Config config, DeviceManager deviceManager, GeofenceManager geofenceManager) { + public OverspeedEventHandler(Config config, DeviceManager deviceManager, CacheManager cacheManager) { this.deviceManager = deviceManager; - this.geofenceManager = geofenceManager; + this.cacheManager = cacheManager; notRepeat = config.getBoolean(Keys.EVENT_OVERSPEED_NOT_REPEAT); minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000; preferLowest = config.getBoolean(Keys.EVENT_OVERSPEED_PREFER_LOWEST); @@ -133,9 +133,9 @@ public class OverspeedEventHandler extends BaseEventHandler { double geofenceSpeedLimit = 0; long overspeedGeofenceId = 0; - if (geofenceManager != null && device.getGeofenceIds() != null) { + if (device.getGeofenceIds() != null) { for (long geofenceId : device.getGeofenceIds()) { - Geofence geofence = geofenceManager.getById(geofenceId); + Geofence geofence = cacheManager.getObject(Geofence.class, geofenceId); if (geofence != null) { double currentSpeedLimit = geofence.getDouble(ATTRIBUTE_SPEED_LIMIT); if (currentSpeedLimit > 0 && geofenceSpeedLimit == 0 diff --git a/src/main/java/org/traccar/helper/UserUtil.java b/src/main/java/org/traccar/helper/UserUtil.java deleted file mode 100644 index 6050ad349..000000000 --- a/src/main/java/org/traccar/helper/UserUtil.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2022 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.helper; - -import org.traccar.model.Server; -import org.traccar.model.User; - -import java.util.TimeZone; - -public final class UserUtil { - - private UserUtil() { - } - - public static String getDistanceUnit(Server server, User user) { - return lookupStringAttribute(server, user, "distanceUnit", "km"); - } - - public static String getSpeedUnit(Server server, User user) { - return lookupStringAttribute(server, user, "speedUnit", "kn"); - } - - public static String getVolumeUnit(Server server, User user) { - return lookupStringAttribute(server, user, "volumeUnit", "ltr"); - } - - public static TimeZone getTimezone(Server server, User user) { - String timezone = lookupStringAttribute(server, user, "timezone", null); - return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); - } - - private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { - String preference; - String serverPreference = server.getString(key); - String userPreference = user.getString(key); - if (server.getForceSettings()) { - preference = serverPreference != null ? serverPreference : userPreference; - } else { - preference = userPreference != null ? userPreference : serverPreference; - } - return preference != null ? preference : defaultValue; - } - -} diff --git a/src/main/java/org/traccar/helper/model/GeofenceUtil.java b/src/main/java/org/traccar/helper/model/GeofenceUtil.java new file mode 100644 index 000000000..f56bf4224 --- /dev/null +++ b/src/main/java/org/traccar/helper/model/GeofenceUtil.java @@ -0,0 +1,40 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper.model; + +import org.traccar.model.Geofence; +import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; + +import java.util.ArrayList; +import java.util.List; + +public final class GeofenceUtil { + + private GeofenceUtil() { + } + + public static List getCurrentGeofences(CacheManager cacheManager, Position position) { + List result = new ArrayList<>(); + for (Geofence geofence : cacheManager.getDeviceObjects(position.getDeviceId(), Geofence.class)) { + if (geofence.getGeometry().containsPoint(position.getLatitude(), position.getLongitude())) { + result.add(geofence.getId()); + } + } + return result; + } + +} diff --git a/src/main/java/org/traccar/helper/model/PositionUtil.java b/src/main/java/org/traccar/helper/model/PositionUtil.java new file mode 100644 index 000000000..64216a937 --- /dev/null +++ b/src/main/java/org/traccar/helper/model/PositionUtil.java @@ -0,0 +1,31 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper.model; + +import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; + +public final class PositionUtil { + + private PositionUtil() { + } + + public static boolean isLatest(CacheManager cacheManager, Position position) { + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + return lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) >= 0; + } + +} diff --git a/src/main/java/org/traccar/helper/model/UserUtil.java b/src/main/java/org/traccar/helper/model/UserUtil.java new file mode 100644 index 000000000..9919e1d95 --- /dev/null +++ b/src/main/java/org/traccar/helper/model/UserUtil.java @@ -0,0 +1,57 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper.model; + +import org.traccar.model.Server; +import org.traccar.model.User; + +import java.util.TimeZone; + +public final class UserUtil { + + private UserUtil() { + } + + public static String getDistanceUnit(Server server, User user) { + return lookupStringAttribute(server, user, "distanceUnit", "km"); + } + + public static String getSpeedUnit(Server server, User user) { + return lookupStringAttribute(server, user, "speedUnit", "kn"); + } + + public static String getVolumeUnit(Server server, User user) { + return lookupStringAttribute(server, user, "volumeUnit", "ltr"); + } + + public static TimeZone getTimezone(Server server, User user) { + String timezone = lookupStringAttribute(server, user, "timezone", null); + return timezone != null ? TimeZone.getTimeZone(timezone) : TimeZone.getDefault(); + } + + private static String lookupStringAttribute(Server server, User user, String key, String defaultValue) { + String preference; + String serverPreference = server.getString(key); + String userPreference = user.getString(key); + if (server.getForceSettings()) { + preference = serverPreference != null ? serverPreference : userPreference; + } else { + preference = userPreference != null ? userPreference : serverPreference; + } + return preference != null ? preference : defaultValue; + } + +} diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 13f42a8b2..2d3b90412 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -17,7 +17,7 @@ package org.traccar.notification; import org.apache.velocity.VelocityContext; -import org.traccar.helper.UserUtil; +import org.traccar.helper.model.UserUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 06375afac..9072ec89e 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -23,7 +23,7 @@ import org.apache.velocity.tools.generic.NumberTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.helper.UserUtil; +import org.traccar.helper.model.UserUtil; import org.traccar.model.Server; import org.traccar.model.User; diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index c9fac4309..27dc5819d 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -29,7 +29,7 @@ import org.jxls.util.JxlsHelper; import org.traccar.Context; import org.traccar.api.security.PermissionsService; import org.traccar.helper.UnitsConverter; -import org.traccar.helper.UserUtil; +import org.traccar.helper.model.UserUtil; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReportItem; diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 71c49f65b..36d5c0fb1 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -31,7 +31,7 @@ import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; -import org.traccar.helper.UserUtil; +import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; import org.traccar.model.Server; import org.traccar.model.User; diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 4b42ea4e5..18daeae15 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -15,6 +15,7 @@ */ package org.traccar.session.cache; +import org.traccar.helper.model.GeofenceUtil; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -181,13 +182,16 @@ public class CacheManager { if (invalidate) { invalidate(object.getClass(), object.getId()); } else { - // TODO if device, also need to update geofences try { lock.writeLock().lock(); deviceCache.get(new CacheKey(object.getClass(), object.getId())).setValue(object); } finally { lock.writeLock().unlock(); } + + if (object instanceof Device) { + invalidateDeviceGeofences((Device) object); + } } } @@ -254,6 +258,8 @@ public class CacheManager { devicePositions.put(deviceId, storage.getObject(Position.class, new Request( new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); } + + invalidateDeviceGeofences(device); } private void unsafeRemoveDevice(long deviceId) { @@ -306,4 +312,11 @@ public class CacheManager { } } + private void invalidateDeviceGeofences(Device device) { + Position position = getPosition(device.getId()); + if (position != null) { + device.setGeofenceIds(GeofenceUtil.getCurrentGeofences(this, position)); + } + } + } -- cgit v1.2.3 From 4dbe47a2362bde8e2a8419b202a02e5e7fc16f87 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 07:08:39 -0700 Subject: Remove more from context --- src/main/java/org/traccar/Context.java | 19 ------------------- src/main/java/org/traccar/Main.java | 3 ++- src/main/java/org/traccar/MainModule.java | 11 +++++++++++ .../java/org/traccar/broadcast/BroadcastService.java | 2 -- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index dcbe6c811..1e158438f 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr353.JSR353Module; import org.apache.velocity.app.VelocityEngine; import org.eclipse.jetty.util.URIUtil; -import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; @@ -132,12 +131,6 @@ public final class Context { return webServer; } - private static BroadcastService broadcastService; - - public static BroadcastService getBroadcastService() { - return broadcastService; - } - private static NotificationManager notificationManager; public static NotificationManager getNotificationManager() { @@ -253,10 +246,6 @@ public final class Context { initEventsModule(); - if (config.hasKey(Keys.BROADCAST_ADDRESS)) { - broadcastService = new BroadcastService(config, objectMapper); - } - if (config.hasKey(Keys.EVENT_FORWARD_URL)) { eventForwarder = new EventForwarder(config); } @@ -288,14 +277,6 @@ public final class Context { velocityEngine.init(velocityProperties); } - public static void init(IdentityManager testIdentityManager) { - config = new Config(); - objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JSR353Module()); - client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); - identityManager = testIdentityManager; - } - public static BaseObjectManager getManager(Class clazz) { if (clazz.equals(Device.class)) { return (BaseObjectManager) deviceManager; diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index b14f22a00..c35ea33a9 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -20,6 +20,7 @@ import com.google.inject.Injector; import com.google.inject.servlet.ServletModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.broadcast.BroadcastService; import org.traccar.schedule.ScheduleManager; import java.io.File; @@ -122,7 +123,7 @@ public final class Main { services.add(injector.getInstance(ServerManager.class)); services.add(Context.getWebServer()); services.add(injector.getInstance(ScheduleManager.class)); - services.add(Context.getBroadcastService()); + services.add(injector.getInstance(BroadcastService.class)); for (LifecycleObject service : services) { if (service != null) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index bb264cff3..c9f2d4e62 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -21,6 +21,7 @@ import com.google.inject.Provides; import com.google.inject.Scopes; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; +import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; @@ -65,6 +66,7 @@ import org.traccar.storage.Storage; import javax.annotation.Nullable; import javax.inject.Singleton; import javax.ws.rs.client.Client; +import java.io.IOException; public class MainModule extends AbstractModule { @@ -247,4 +249,13 @@ public class MainModule extends AbstractModule { return null; } + @Provides + public static BroadcastService provideBroadcastService( + Config config, ObjectMapper objectMapper) throws IOException { + if (config.hasKey(Keys.BROADCAST_ADDRESS)) { + return new BroadcastService(config, objectMapper); + } + return null; + } + } diff --git a/src/main/java/org/traccar/broadcast/BroadcastService.java b/src/main/java/org/traccar/broadcast/BroadcastService.java index b17857fcd..26e38400b 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastService.java +++ b/src/main/java/org/traccar/broadcast/BroadcastService.java @@ -22,7 +22,6 @@ import org.traccar.LifecycleObject; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; @@ -46,7 +45,6 @@ public class BroadcastService implements LifecycleObject { private final ExecutorService service = Executors.newSingleThreadExecutor(); private final byte[] receiverBuffer = new byte[4096]; - @Inject public BroadcastService(Config config, ObjectMapper objectMapper) throws IOException { this.objectMapper = objectMapper; address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); -- cgit v1.2.3 From 6f163bdf3856323a5aa075f9a2e1aeb01b7bc598 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 08:53:26 -0700 Subject: Remove more from context --- src/main/java/org/traccar/Context.java | 20 -------------------- src/main/java/org/traccar/MainModule.java | 6 ------ .../org/traccar/reports/StopsReportProvider.java | 7 +++++-- .../org/traccar/reports/TripsReportProvider.java | 7 +++++-- .../java/org/traccar/reports/common/TripsConfig.java | 20 +++++++++++++++++++- 5 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 1e158438f..46c761094 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -41,7 +41,6 @@ import org.traccar.model.Notification; import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; -import org.traccar.reports.common.TripsConfig; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; @@ -167,23 +166,6 @@ public final class Context { return smsManager; } - private static TripsConfig tripsConfig; - - public static TripsConfig getTripsConfig() { - return tripsConfig; - } - - public static TripsConfig initTripsConfig() { - return new TripsConfig( - config.getLong(Keys.REPORT_TRIP_MINIMAL_TRIP_DISTANCE), - config.getLong(Keys.REPORT_TRIP_MINIMAL_TRIP_DURATION) * 1000, - config.getLong(Keys.REPORT_TRIP_MINIMAL_PARKING_DURATION) * 1000, - config.getLong(Keys.REPORT_TRIP_MINIMAL_NO_DATA_DURATION) * 1000, - config.getBoolean(Keys.REPORT_TRIP_USE_IGNITION), - config.getBoolean(Keys.EVENT_MOTION_PROCESS_INVALID_POSITIONS), - config.getDouble(Keys.EVENT_MOTION_SPEED_THRESHOLD)); - } - private static class ObjectMapperContextResolver implements ContextResolver { @Override @@ -236,8 +218,6 @@ public final class Context { connectionManager = new ConnectionManager(); - tripsConfig = initTripsConfig(); - if (config.hasKey(Keys.SMS_HTTP_URL)) { smsManager = new HttpSmsClient(); } else if (config.hasKey(Keys.SMS_AWS_REGION)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index c9f2d4e62..d070c9fd7 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -57,7 +57,6 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; -import org.traccar.reports.common.TripsConfig; import org.traccar.sms.SmsManager; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; @@ -110,11 +109,6 @@ public class MainModule extends AbstractModule { return Context.getClient(); } - @Provides - public static TripsConfig provideTripsConfig() { - return Context.getTripsConfig(); - } - @Provides public static DeviceManager provideDeviceManager() { return Context.getDeviceManager(); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 8899dc42f..b7896c423 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -34,6 +34,7 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; import org.traccar.storage.Storage; @@ -45,11 +46,13 @@ public class StopsReportProvider { private final PermissionsService permissionsService; private final Storage storage; + private final TripsConfig tripsConfig; @Inject - public StopsReportProvider(PermissionsService permissionsService, Storage storage) { + public StopsReportProvider(PermissionsService permissionsService, Storage storage, TripsConfig tripsConfig) { this.permissionsService = permissionsService; this.storage = storage; + this.tripsConfig = tripsConfig; } private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { @@ -61,7 +64,7 @@ public class StopsReportProvider { return ReportUtils.detectTripsAndStops( storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, StopReportItem.class); + tripsConfig, ignoreOdometer, StopReportItem.class); } public Collection getObjects( diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index bcd79ab25..0505baaa1 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -33,6 +33,7 @@ import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; import org.traccar.storage.Storage; @@ -44,11 +45,13 @@ public class TripsReportProvider { private final PermissionsService permissionsService; private final Storage storage; + private final TripsConfig tripsConfig; @Inject - public TripsReportProvider(PermissionsService permissionsService, Storage storage) { + public TripsReportProvider(PermissionsService permissionsService, Storage storage, TripsConfig tripsConfig) { this.permissionsService = permissionsService; this.storage = storage; + this.tripsConfig = tripsConfig; } private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { @@ -60,7 +63,7 @@ public class TripsReportProvider { return ReportUtils.detectTripsAndStops( storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - Context.getTripsConfig(), ignoreOdometer, TripReportItem.class); + tripsConfig, ignoreOdometer, TripReportItem.class); } public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, diff --git a/src/main/java/org/traccar/reports/common/TripsConfig.java b/src/main/java/org/traccar/reports/common/TripsConfig.java index 9a7cebafb..c28cbeed4 100644 --- a/src/main/java/org/traccar/reports/common/TripsConfig.java +++ b/src/main/java/org/traccar/reports/common/TripsConfig.java @@ -16,9 +16,27 @@ */ package org.traccar.reports.common; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Inject; + public class TripsConfig { - public TripsConfig(double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, + @Inject + public TripsConfig(Config config) { + this( + config.getLong(Keys.REPORT_TRIP_MINIMAL_TRIP_DISTANCE), + config.getLong(Keys.REPORT_TRIP_MINIMAL_TRIP_DURATION) * 1000, + config.getLong(Keys.REPORT_TRIP_MINIMAL_PARKING_DURATION) * 1000, + config.getLong(Keys.REPORT_TRIP_MINIMAL_NO_DATA_DURATION) * 1000, + config.getBoolean(Keys.REPORT_TRIP_USE_IGNITION), + config.getBoolean(Keys.EVENT_MOTION_PROCESS_INVALID_POSITIONS), + config.getDouble(Keys.EVENT_MOTION_SPEED_THRESHOLD)); + } + + public TripsConfig( + double minimalTripDistance, long minimalTripDuration, long minimalParkingDuration, long minimalNoDataDuration, boolean useIgnition, boolean processInvalidPositions, double speedThreshold) { this.minimalTripDistance = minimalTripDistance; this.minimalTripDuration = minimalTripDuration; -- cgit v1.2.3 From 5b6bba55d960dcf4fc7721d1d2e75b950bb13809 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 16:22:40 -0700 Subject: Make singleton --- src/main/java/org/traccar/database/StatisticsManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index 3579ce7a5..d5a179cbe 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import org.traccar.model.Statistics; import org.traccar.storage.StorageException; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Form; @@ -37,6 +38,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +@Singleton public class StatisticsManager { private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsManager.class); -- cgit v1.2.3 From 29b5d05cfd66a9f51b7ce272c1fb07077bc715b2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 17:09:52 -0700 Subject: Remove WebServer from context --- src/main/java/org/traccar/Context.java | 11 ---------- src/main/java/org/traccar/Main.java | 32 ++++++++++++---------------- src/main/java/org/traccar/MainModule.java | 9 ++++++++ src/main/java/org/traccar/web/WebServer.java | 2 ++ 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 46c761094..3e4cc1bb9 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -46,7 +46,6 @@ import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; -import org.traccar.web.WebServer; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; @@ -124,12 +123,6 @@ public final class Context { return Main.getInjector() != null ? Main.getInjector().getInstance(Geocoder.class) : null; } - private static WebServer webServer; - - public static WebServer getWebServer() { - return webServer; - } - private static NotificationManager notificationManager; public static NotificationManager getNotificationManager() { @@ -210,10 +203,6 @@ public final class Context { identityManager = deviceManager; - if (config.hasKey(Keys.WEB_PORT)) { - webServer = new WebServer(config); - } - permissionsManager = new PermissionsManager(dataManager, usersManager); connectionManager = new ConnectionManager(); diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index c35ea33a9..412ac1f5e 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; import org.traccar.schedule.ScheduleManager; +import org.traccar.web.WebServer; import java.io.File; import java.lang.management.ManagementFactory; @@ -29,10 +30,10 @@ import java.lang.management.MemoryMXBean; import java.lang.management.OperatingSystemMXBean; import java.lang.management.RuntimeMXBean; import java.nio.charset.Charset; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; import java.util.Locale; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; public final class Main { @@ -119,28 +120,23 @@ public final class Main { LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); LOGGER.info("Starting server..."); - List services = new LinkedList<>(); - services.add(injector.getInstance(ServerManager.class)); - services.add(Context.getWebServer()); - services.add(injector.getInstance(ScheduleManager.class)); - services.add(injector.getInstance(BroadcastService.class)); + var services = Stream.of( + ServerManager.class, WebServer.class, ScheduleManager.class, BroadcastService.class) + .map(injector::getInstance) + .filter(Objects::nonNull) + .collect(Collectors.toList()); - for (LifecycleObject service : services) { - if (service != null) { - service.start(); - } + for (var service : services) { + service.start(); } Thread.setDefaultUncaughtExceptionHandler((t, e) -> LOGGER.error("Thread exception", e)); Runtime.getRuntime().addShutdownHook(new Thread(() -> { - LOGGER.info("Shutting down server..."); + LOGGER.info("Stopping server..."); - Collections.reverse(services); - for (LifecycleObject service : services) { - if (service != null) { - service.stop(); - } + for (var service : services) { + service.stop(); } })); } catch (Exception e) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index d070c9fd7..9ec73d819 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -61,6 +61,7 @@ import org.traccar.sms.SmsManager; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.Storage; +import org.traccar.web.WebServer; import javax.annotation.Nullable; import javax.inject.Singleton; @@ -128,6 +129,14 @@ public class MainModule extends AbstractModule { return null; } + @Provides + public static WebServer provideWebServer(Config config) { + if (config.hasKey(Keys.WEB_PORT)) { + return new WebServer(config); + } + return null; + } + @Singleton @Provides public static Geocoder provideGeocoder(Config config) { diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index f1ee8fcb2..fdbfc1464 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -60,6 +60,7 @@ import org.traccar.api.security.SecurityRequestFilter; import org.traccar.api.resource.ServerResource; import org.traccar.config.Keys; +import javax.inject.Inject; import javax.servlet.DispatcherType; import javax.servlet.ServletException; import javax.servlet.SessionCookieConfig; @@ -79,6 +80,7 @@ public class WebServer implements LifecycleObject { private final Server server; + @Inject public WebServer(Config config) { String address = config.getString(Keys.WEB_ADDRESS); int port = config.getInteger(Keys.WEB_PORT); -- cgit v1.2.3 From adafc5f6130854dd88c191dd04489073419ee41d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 17:56:37 -0700 Subject: Remove SMS from context --- src/main/java/org/traccar/BaseProtocol.java | 18 +++++-- src/main/java/org/traccar/Context.java | 15 ------ src/main/java/org/traccar/MainModule.java | 12 ++++- src/main/java/org/traccar/ServerManager.java | 6 ++- src/main/java/org/traccar/config/Keys.java | 8 ++++ .../traccar/notification/NotificatorManager.java | 56 ++++++++-------------- .../org/traccar/notificators/NotificatorSms.java | 24 +++++++--- 7 files changed, 74 insertions(+), 65 deletions(-) diff --git a/src/main/java/org/traccar/BaseProtocol.java b/src/main/java/org/traccar/BaseProtocol.java index ec1933dc8..d19fc307e 100644 --- a/src/main/java/org/traccar/BaseProtocol.java +++ b/src/main/java/org/traccar/BaseProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,7 +21,10 @@ import io.netty.channel.Channel; import io.netty.handler.codec.string.StringEncoder; import org.traccar.helper.DataConverter; import org.traccar.model.Command; +import org.traccar.sms.SmsManager; +import javax.annotation.Nullable; +import javax.inject.Inject; import java.net.SocketAddress; import java.util.Arrays; import java.util.Collection; @@ -37,6 +40,8 @@ public abstract class BaseProtocol implements Protocol { private final Set supportedTextCommands = new HashSet<>(); private final List connectorList = new LinkedList<>(); + private SmsManager smsManager; + private StringProtocolEncoder textCommandEncoder = null; public static String nameFromClass(Class clazz) { @@ -48,6 +53,11 @@ public abstract class BaseProtocol implements Protocol { name = nameFromClass(getClass()); } + @Inject + public void setSmsManager(@Nullable SmsManager smsManager) { + this.smsManager = smsManager; + } + @Override public String getName() { return name; @@ -111,13 +121,13 @@ public abstract class BaseProtocol implements Protocol { @Override public void sendTextCommand(String destAddress, Command command) throws Exception { - if (Context.getSmsManager() != null) { + if (smsManager != null) { if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmsManager().sendMessage(destAddress, command.getString(Command.KEY_DATA), true); + smsManager.sendMessage(destAddress, command.getString(Command.KEY_DATA), true); } else if (supportedTextCommands.contains(command.getType()) && textCommandEncoder != null) { String encodedCommand = (String) textCommandEncoder.encodeCommand(command); if (encodedCommand != null) { - Context.getSmsManager().sendMessage(destAddress, encodedCommand, true); + smsManager.sendMessage(destAddress, encodedCommand, true); } else { throw new RuntimeException("Failed to encode command"); } diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 3e4cc1bb9..5011764c6 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -43,9 +43,6 @@ import org.traccar.notification.EventForwarder; import org.traccar.notification.NotificatorManager; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; -import org.traccar.sms.HttpSmsClient; -import org.traccar.sms.SmsManager; -import org.traccar.sms.SnsSmsClient; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; @@ -153,12 +150,6 @@ public final class Context { return eventForwarder; } - private static SmsManager smsManager; - - public static SmsManager getSmsManager() { - return smsManager; - } - private static class ObjectMapperContextResolver implements ContextResolver { @Override @@ -207,12 +198,6 @@ public final class Context { connectionManager = new ConnectionManager(); - if (config.hasKey(Keys.SMS_HTTP_URL)) { - smsManager = new HttpSmsClient(); - } else if (config.hasKey(Keys.SMS_AWS_REGION)) { - smsManager = new SnsSmsClient(); - } - initEventsModule(); if (config.hasKey(Keys.EVENT_FORWARD_URL)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 9ec73d819..f6621a18e 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -57,7 +57,9 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; +import org.traccar.sms.SnsSmsClient; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; import org.traccar.storage.Storage; @@ -115,9 +117,15 @@ public class MainModule extends AbstractModule { return Context.getDeviceManager(); } + @Singleton @Provides - public static SmsManager provideSmsManager() { - return Context.getSmsManager(); + public static SmsManager provideSmsManager(Config config) { + if (config.hasKey(Keys.SMS_HTTP_URL)) { + return new HttpSmsClient(); + } else if (config.hasKey(Keys.SMS_AWS_REGION)) { + return new SnsSmsClient(); + } + return null; } @Singleton diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index a6bb6888c..f4f6e1ba4 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -15,11 +15,13 @@ */ package org.traccar; +import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Keys; import org.traccar.helper.ClassScanner; +import javax.inject.Inject; import javax.inject.Singleton; import java.io.IOException; import java.net.BindException; @@ -38,10 +40,12 @@ public class ServerManager implements LifecycleObject { private final List connectorList = new LinkedList<>(); private final Map protocolList = new ConcurrentHashMap<>(); - public ServerManager() throws IOException, URISyntaxException, ReflectiveOperationException { + @Inject + public ServerManager(Injector injector) throws IOException, URISyntaxException, ReflectiveOperationException { for (Class protocolClass : ClassScanner.findSubclasses(BaseProtocol.class, "org.traccar.protocol")) { if (Context.getConfig().hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { BaseProtocol protocol = (BaseProtocol) protocolClass.getDeclaredConstructor().newInstance(); + injector.injectMembers(protocol); connectorList.addAll(protocol.getConnectorList()); protocolList.put(protocol.getName(), protocol); } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index ba576397b..d53245c65 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -753,6 +753,14 @@ public final class Keys { "sms.aws.region", Collections.singletonList(KeyType.GLOBAL)); + /** + * Enabled notification options. Comma-separated string is expected. + * Example: web,mail,sms + */ + public static final ConfigKey NOTIFICATOR_TYPES = new ConfigKey<>( + "notificator.types", + Collections.singletonList(KeyType.GLOBAL)); + /** * Traccar notification API key. */ diff --git a/src/main/java/org/traccar/notification/NotificatorManager.java b/src/main/java/org/traccar/notification/NotificatorManager.java index dfd8cd3d6..9705377b4 100644 --- a/src/main/java/org/traccar/notification/NotificatorManager.java +++ b/src/main/java/org/traccar/notification/NotificatorManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,6 +24,8 @@ import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; +import org.traccar.config.Keys; import org.traccar.model.Typed; import org.traccar.notificators.NotificatorFirebase; import org.traccar.notificators.NotificatorMail; @@ -39,45 +41,25 @@ public final class NotificatorManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorManager.class); - private static final Notificator NULL_NOTIFICATOR = new NotificatorNull(); + private static final Map> NOTIFICATORS_ALL = Map.of( + "web", NotificatorWeb.class, + "mail", NotificatorMail.class, + "sms", NotificatorSms.class, + "firebase", NotificatorFirebase.class, + "traccar", NotificatorTraccar.class, + "telegram", NotificatorTelegram.class, + "pushover", NotificatorPushover.class); private final Map notificators = new HashMap<>(); public NotificatorManager() { - final String[] types = Context.getConfig().getString("notificator.types", "").split(","); - for (String type : types) { - String defaultNotificator = ""; - switch (type) { - case "web": - defaultNotificator = NotificatorWeb.class.getCanonicalName(); - break; - case "mail": - defaultNotificator = NotificatorMail.class.getCanonicalName(); - break; - case "sms": - defaultNotificator = NotificatorSms.class.getCanonicalName(); - break; - case "firebase": - defaultNotificator = NotificatorFirebase.class.getCanonicalName(); - break; - case "traccar": - defaultNotificator = NotificatorTraccar.class.getCanonicalName(); - break; - case "telegram": - defaultNotificator = NotificatorTelegram.class.getCanonicalName(); - break; - case "pushover": - defaultNotificator = NotificatorPushover.class.getCanonicalName(); - break; - default: - break; - } - final String className = Context.getConfig() - .getString("notificator." + type + ".class", defaultNotificator); - try { - notificators.put(type, (Notificator) Class.forName(className).newInstance()); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { - LOGGER.warn("Unable to load notificator class for " + type + " " + className + " " + e.getMessage()); + String types = Context.getConfig().getString(Keys.NOTIFICATOR_TYPES); + if (types != null) { + for (String type : types.split(",")) { + var notificatorClass = NOTIFICATORS_ALL.get(type); + if (notificatorClass != null) { + notificators.put(type, Main.getInjector().getInstance(notificatorClass)); + } } } } @@ -86,7 +68,7 @@ public final class NotificatorManager { final Notificator notificator = notificators.get(type); if (notificator == null) { LOGGER.warn("No notificator configured for type : " + type); - return NULL_NOTIFICATOR; + return new NotificatorNull(); } return notificator; } diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index f35b797cd..f4d1de0cb 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -16,8 +16,6 @@ */ package org.traccar.notificators; -import org.traccar.Context; -import org.traccar.Main; import org.traccar.database.StatisticsManager; import org.traccar.model.Event; import org.traccar.model.Position; @@ -26,16 +24,30 @@ import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import org.traccar.notification.NotificationMessage; import org.traccar.session.cache.CacheManager; +import org.traccar.sms.SmsManager; -public final class NotificatorSms implements Notificator { +import javax.inject.Inject; + +public class NotificatorSms implements Notificator { + + private final SmsManager smsManager; + private final CacheManager cacheManager; + private final StatisticsManager statisticsManager; + + @Inject + public NotificatorSms(SmsManager smsManager, CacheManager cacheManager, StatisticsManager statisticsManager) { + this.smsManager = smsManager; + this.cacheManager = cacheManager; + this.statisticsManager = statisticsManager; + } @Override public void send(User user, Event event, Position position) throws MessageException, InterruptedException { if (user.getPhone() != null) { NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); - Main.getInjector().getInstance(StatisticsManager.class).registerSms(); - Context.getSmsManager().sendMessage(user.getPhone(), shortMessage.getBody(), false); + cacheManager, user, event, position, "short"); + statisticsManager.registerSms(); + smsManager.sendMessage(user.getPhone(), shortMessage.getBody(), false); } } -- cgit v1.2.3 From 336d6c4353fd77ad268aaf5cfe9c0296edfb0201 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Jun 2022 18:03:52 -0700 Subject: Remove more from context --- src/main/java/org/traccar/Context.java | 12 ++++-------- .../org/traccar/api/resource/NotificationResource.java | 14 +++++++++----- .../java/org/traccar/database/NotificationManager.java | 8 ++++++-- .../java/org/traccar/notification/NotificatorManager.java | 13 +++++++++---- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 5011764c6..42a92f436 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -126,12 +126,6 @@ public final class Context { return notificationManager; } - private static NotificatorManager notificatorManager; - - public static NotificatorManager getNotificatorManager() { - return notificatorManager; - } - private static VelocityEngine velocityEngine; public static VelocityEngine getVelocityEngine() { @@ -208,8 +202,10 @@ public final class Context { private static void initEventsModule() { - notificationManager = new NotificationManager(dataManager, Main.getInjector().getInstance(CacheManager.class)); - notificatorManager = new NotificatorManager(); + notificationManager = new NotificationManager( + dataManager, + Main.getInjector().getInstance(CacheManager.class), + Main.getInjector().getInstance(NotificatorManager.class)); Properties velocityProperties = new Properties(); velocityProperties.setProperty("file.resource.loader.path", Context.getConfig().getString("templates.rootPath", "templates") + "/"); diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index 9ea811473..0a95b257a 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import java.util.Collection; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -33,6 +34,7 @@ import org.traccar.model.Notification; import org.traccar.model.Typed; import org.traccar.model.User; import org.traccar.notification.MessageException; +import org.traccar.notification.NotificatorManager; import org.traccar.storage.StorageException; @Path("notifications") @@ -40,6 +42,9 @@ import org.traccar.storage.StorageException; @Consumes(MediaType.APPLICATION_JSON) public class NotificationResource extends ExtendedObjectResource { + @Inject + private NotificatorManager notificatorManager; + public NotificationResource() { super(Notification.class); } @@ -53,16 +58,15 @@ public class NotificationResource extends ExtendedObjectResource { @GET @Path("notificators") public Collection getNotificators() { - return Context.getNotificatorManager().getAllNotificatorTypes(); + return notificatorManager.getAllNotificatorTypes(); } @POST @Path("test") public Response testMessage() throws MessageException, InterruptedException, StorageException { User user = permissionsService.getUser(getUserId()); - for (Typed method : Context.getNotificatorManager().getAllNotificatorTypes()) { - Context.getNotificatorManager() - .getNotificator(method.getType()).send(user, new Event("test", 0), null); + for (Typed method : notificatorManager.getAllNotificatorTypes()) { + notificatorManager.getNotificator(method.getType()).send(user, new Event("test", 0), null); } return Response.noContent().build(); } @@ -72,7 +76,7 @@ public class NotificationResource extends ExtendedObjectResource { public Response testMessage(@PathParam("notificator") String notificator) throws MessageException, InterruptedException, StorageException { User user = permissionsService.getUser(getUserId()); - Context.getNotificatorManager().getNotificator(notificator).send(user, new Event("test", 0), null); + notificatorManager.getNotificator(notificator).send(user, new Event("test", 0), null); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index fcefb54f0..eddd7e2b4 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -37,6 +37,7 @@ import org.traccar.model.Position; import org.traccar.model.Typed; import org.traccar.model.User; import org.traccar.notification.MessageException; +import org.traccar.notification.NotificatorManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; @@ -45,12 +46,15 @@ public class NotificationManager extends ExtendedObjectManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); private final CacheManager cacheManager; + private final NotificatorManager notificatorManager; private final boolean geocodeOnRequest; - public NotificationManager(DataManager dataManager, CacheManager cacheManager) { + public NotificationManager( + DataManager dataManager, CacheManager cacheManager, NotificatorManager notificatorManager) { super(dataManager, Notification.class); this.cacheManager = cacheManager; + this.notificatorManager = notificatorManager; geocodeOnRequest = Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST); } @@ -116,7 +120,7 @@ public class NotificationManager extends ExtendedObjectManager { new Thread(() -> { for (String notificator : notificators) { try { - Context.getNotificatorManager().getNotificator(notificator).send(user, event, position); + notificatorManager.getNotificator(notificator).send(user, event, position); } catch (MessageException | InterruptedException exception) { LOGGER.warn("Notification failed", exception); } diff --git a/src/main/java/org/traccar/notification/NotificatorManager.java b/src/main/java/org/traccar/notification/NotificatorManager.java index 9705377b4..d6ebb2c4a 100644 --- a/src/main/java/org/traccar/notification/NotificatorManager.java +++ b/src/main/java/org/traccar/notification/NotificatorManager.java @@ -23,8 +23,8 @@ import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.Main; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Typed; import org.traccar.notificators.NotificatorFirebase; @@ -37,7 +37,11 @@ import org.traccar.notificators.NotificatorWeb; import org.traccar.notificators.NotificatorTelegram; import org.traccar.notificators.NotificatorPushover; -public final class NotificatorManager { +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class NotificatorManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorManager.class); @@ -52,8 +56,9 @@ public final class NotificatorManager { private final Map notificators = new HashMap<>(); - public NotificatorManager() { - String types = Context.getConfig().getString(Keys.NOTIFICATOR_TYPES); + @Inject + public NotificatorManager(Config config) { + String types = config.getString(Keys.NOTIFICATOR_TYPES); if (types != null) { for (String type : types.split(",")) { var notificatorClass = NOTIFICATORS_ALL.get(type); -- cgit v1.2.3 From c03b4a2ace925e6a0d7c43ce59e14ddb9cbf18a9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Jun 2022 07:06:43 -0700 Subject: Inject mail manager --- src/main/java/org/traccar/Context.java | 9 --------- .../org/traccar/api/resource/PasswordResource.java | 7 ++++++- .../java/org/traccar/api/resource/ReportResource.java | 8 +++++--- .../java/org/traccar/api/resource/ServerResource.java | 8 +++++++- src/main/java/org/traccar/database/MailManager.java | 16 ++++++++++++---- src/main/java/org/traccar/model/Server.java | 10 ++++++++-- .../org/traccar/notificators/NotificatorMail.java | 19 ++++++++++++++----- 7 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 42a92f436..cba4c0a58 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -27,7 +27,6 @@ import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; -import org.traccar.database.MailManager; import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; @@ -80,12 +79,6 @@ public final class Context { return dataManager; } - private static MailManager mailManager; - - public static MailManager getMailManager() { - return mailManager; - } - private static UsersManager usersManager; public static UsersManager getUsersManager() { @@ -178,8 +171,6 @@ public final class Context { dataManager = new DataManager(config); } - mailManager = new MailManager(); - if (dataManager != null) { usersManager = new UsersManager(dataManager); groupsManager = new GroupsManager(dataManager); diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 91d994153..7df25c264 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -18,12 +18,14 @@ package org.traccar.api.resource; import org.apache.velocity.VelocityContext; import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.MailManager; import org.traccar.model.User; import org.traccar.notification.NotificationMessage; import org.traccar.notification.TextTemplateFormatter; import org.traccar.storage.StorageException; import javax.annotation.security.PermitAll; +import javax.inject.Inject; import javax.mail.MessagingException; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; @@ -41,6 +43,9 @@ public class PasswordResource extends BaseResource { private static final String PASSWORD_RESET_TOKEN = "passwordToken"; + @Inject + private MailManager mailManager; + @Path("reset") @PermitAll @POST @@ -56,7 +61,7 @@ public class PasswordResource extends BaseResource { velocityContext.put("token", token); NotificationMessage fullMessage = TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); - Context.getMailManager().sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); + mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); break; } } diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 3c1b8f715..3955f1d20 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -38,8 +38,8 @@ import javax.ws.rs.core.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.MailManager; import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; @@ -80,6 +80,9 @@ public class ReportResource extends BaseResource { @Inject private TripsReportProvider tripsReportProvider; + @Inject + private MailManager mailManager; + private interface ReportExecutor { void execute(ByteArrayOutputStream stream) throws StorageException, IOException; } @@ -99,8 +102,7 @@ public class ReportResource extends BaseResource { stream.toByteArray(), "application/octet-stream"))); User user = permissionsService.getUser(userId); - Context.getMailManager().sendMessage( - user, "Report", "The report is in the attachment.", attachment); + mailManager.sendMessage(user, "Report", "The report is in the attachment.", attachment); } catch (StorageException | IOException | MessagingException e) { LOGGER.warn("Report failed", e); } diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index f238e8905..51a26825b 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.MailManager; import org.traccar.helper.LogAction; import org.traccar.model.Server; import org.traccar.storage.Storage; @@ -46,10 +47,15 @@ public class ServerResource extends BaseResource { @Inject private Storage storage; + @Inject + private MailManager mailManager; + @PermitAll @GET public Server get() throws StorageException { - return storage.getObject(Server.class, new Request(new Columns.All())); + Server server = storage.getObject(Server.class, new Request(new Columns.All())); + server.setEmailEnabled(mailManager.getEmailEnabled()); + return server; } @PUT diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index 21fee5ee7..54f617d5f 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -18,11 +18,12 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.Main; +import org.traccar.config.Config; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; +import javax.inject.Inject; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.MessagingException; @@ -40,6 +41,13 @@ public final class MailManager { private static final Logger LOGGER = LoggerFactory.getLogger(MailManager.class); + private final Config config; + + @Inject + public MailManager(Config config) { + this.config = config; + } + private static Properties getProperties(PropertiesProvider provider) { Properties properties = new Properties(); String host = provider.getString("mail.smtp.host"); @@ -88,7 +96,7 @@ public final class MailManager { } public boolean getEmailEnabled() { - return Context.getConfig().hasKey("mail.smtp.host"); + return config.hasKey("mail.smtp.host"); } public void sendMessage( @@ -99,11 +107,11 @@ public final class MailManager { public void sendMessage( User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { Properties properties = null; - if (!Context.getConfig().getBoolean("mail.smtp.ignoreUserConfig")) { + if (!config.getBoolean("mail.smtp.ignoreUserConfig")) { properties = getProperties(new PropertiesProvider(user)); } if (properties == null || !properties.containsKey("mail.smtp.host")) { - properties = getProperties(new PropertiesProvider(Context.getConfig())); + properties = getProperties(new PropertiesProvider(config)); } if (!properties.containsKey("mail.smtp.host")) { LOGGER.warn("No SMTP configuration found"); diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index 7cffd7eac..c5640fb97 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -16,7 +16,6 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import org.traccar.Context; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @@ -193,9 +192,16 @@ public class Server extends ExtendedModel implements UserRestrictions { return getClass().getPackage().getImplementationVersion(); } + private boolean emailEnabled; + + @QueryIgnore + public void setEmailEnabled(boolean emailEnabled) { + this.emailEnabled = emailEnabled; + } + @QueryIgnore public Boolean getEmailEnabled() { - return Context.getMailManager().getEmailEnabled(); + return emailEnabled; } } diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index fd7cae7c3..fe8d69af2 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -16,8 +16,7 @@ */ package org.traccar.notificators; -import org.traccar.Context; -import org.traccar.Main; +import org.traccar.database.MailManager; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; @@ -26,16 +25,26 @@ import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import org.traccar.session.cache.CacheManager; +import javax.inject.Inject; import javax.mail.MessagingException; -public final class NotificatorMail implements Notificator { +public class NotificatorMail implements Notificator { + + private final MailManager mailManager; + private final CacheManager cacheManager; + + @Inject + public NotificatorMail(MailManager mailManager, CacheManager cacheManager) { + this.mailManager = mailManager; + this.cacheManager = cacheManager; + } @Override public void send(User user, Event event, Position position) throws MessageException { try { NotificationMessage fullMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "full"); - Context.getMailManager().sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); + cacheManager, user, event, position, "full"); + mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); } -- cgit v1.2.3 From bbe84d6a751fdc840e4201ef9027a96527006049 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Jun 2022 07:56:49 -0700 Subject: Inject report utils --- src/main/java/org/traccar/Context.java | 7 +- .../org/traccar/api/resource/ServerResource.java | 10 +- .../org/traccar/database/NotificationManager.java | 14 +- .../traccar/handler/events/MotionEventHandler.java | 11 +- .../org/traccar/helper/model/PositionUtil.java | 13 ++ .../org/traccar/reports/EventsReportProvider.java | 64 ++++---- .../org/traccar/reports/RouteReportProvider.java | 43 +++--- .../org/traccar/reports/StopsReportProvider.java | 62 +++----- .../org/traccar/reports/SummaryReportProvider.java | 43 +++--- .../org/traccar/reports/TripsReportProvider.java | 54 +++---- .../org/traccar/reports/common/ReportUtils.java | 165 +++++++++++---------- .../java/org/traccar/reports/ReportUtilsTest.java | 78 ++++++---- 12 files changed, 282 insertions(+), 282 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index cba4c0a58..471416926 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -109,10 +109,6 @@ public final class Context { return permissionsManager; } - public static Geocoder getGeocoder() { - return Main.getInjector() != null ? Main.getInjector().getInstance(Geocoder.class) : null; - } - private static NotificationManager notificationManager; public static NotificationManager getNotificationManager() { @@ -196,7 +192,8 @@ public final class Context { notificationManager = new NotificationManager( dataManager, Main.getInjector().getInstance(CacheManager.class), - Main.getInjector().getInstance(NotificatorManager.class)); + Main.getInjector().getInstance(NotificatorManager.class), + Main.getInjector().getInstance(Geocoder.class)); Properties velocityProperties = new Properties(); velocityProperties.setProperty("file.resource.loader.path", Context.getConfig().getString("templates.rootPath", "templates") + "/"); diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 51a26825b..18230a2b3 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -18,6 +18,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.database.MailManager; +import org.traccar.geocoder.Geocoder; import org.traccar.helper.LogAction; import org.traccar.model.Server; import org.traccar.storage.Storage; @@ -25,6 +26,7 @@ import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; +import javax.annotation.Nullable; import javax.annotation.security.PermitAll; import javax.inject.Inject; import javax.ws.rs.Consumes; @@ -50,6 +52,10 @@ public class ServerResource extends BaseResource { @Inject private MailManager mailManager; + @Inject + @Nullable + private Geocoder geocoder; + @PermitAll @GET public Server get() throws StorageException { @@ -69,8 +75,8 @@ public class ServerResource extends BaseResource { @Path("geocode") @GET public String geocode(@QueryParam("latitude") double latitude, @QueryParam("longitude") double longitude) { - if (Context.getGeocoder() != null) { - return Context.getGeocoder().getAddress(latitude, longitude, null); + if (geocoder != null) { + return geocoder.getAddress(latitude, longitude, null); } else { throw new RuntimeException("Reverse geocoding is not enabled"); } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index eddd7e2b4..1f4a48ac0 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -30,6 +30,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.config.Keys; +import org.traccar.geocoder.Geocoder; import org.traccar.model.Calendar; import org.traccar.model.Event; import org.traccar.model.Notification; @@ -41,20 +42,25 @@ import org.traccar.notification.NotificatorManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; +import javax.annotation.Nullable; + public class NotificationManager extends ExtendedObjectManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); private final CacheManager cacheManager; private final NotificatorManager notificatorManager; + private final Geocoder geocoder; private final boolean geocodeOnRequest; public NotificationManager( - DataManager dataManager, CacheManager cacheManager, NotificatorManager notificatorManager) { + DataManager dataManager, CacheManager cacheManager, + NotificatorManager notificatorManager, @Nullable Geocoder geocoder) { super(dataManager, Notification.class); this.cacheManager = cacheManager; this.notificatorManager = notificatorManager; + this.geocoder = geocoder; geocodeOnRequest = Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST); } @@ -110,10 +116,8 @@ public class NotificationManager extends ExtendedObjectManager { } } - if (position != null && position.getAddress() == null - && geocodeOnRequest && Context.getGeocoder() != null) { - position.setAddress(Context.getGeocoder() - .getAddress(position.getLatitude(), position.getLongitude(), null)); + if (position != null && position.getAddress() == null && geocodeOnRequest && geocoder != null) { + position.setAddress(geocoder.getAddress(position.getLatitude(), position.getLongitude(), null)); } User user = Context.getUsersManager().getById(userId); diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 57d2bc1c5..2c381e530 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -16,20 +16,19 @@ */ package org.traccar.handler.events; -import java.util.Collections; -import java.util.Map; - import io.netty.channel.ChannelHandler; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; -import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.reports.common.ReportUtils; import org.traccar.reports.common.TripsConfig; +import org.traccar.session.DeviceState; import javax.inject.Inject; +import java.util.Collections; +import java.util.Map; @ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { @@ -89,7 +88,7 @@ public class MotionEventHandler extends BaseEventHandler { Position motionPosition = deviceState.getMotionPosition(); if (motionPosition != null) { long motionTime = motionPosition.getFixTime().getTime(); - double distance = ReportUtils.calculateDistance(motionPosition, position, false); + double distance = PositionUtil.calculateDistance(motionPosition, position, false); Boolean ignition = null; if (tripsConfig.getUseIgnition() && position.getAttributes().containsKey(Position.KEY_IGNITION)) { diff --git a/src/main/java/org/traccar/helper/model/PositionUtil.java b/src/main/java/org/traccar/helper/model/PositionUtil.java index 64216a937..644517dac 100644 --- a/src/main/java/org/traccar/helper/model/PositionUtil.java +++ b/src/main/java/org/traccar/helper/model/PositionUtil.java @@ -28,4 +28,17 @@ public final class PositionUtil { return lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) >= 0; } + public static double calculateDistance(Position first, Position last, boolean useOdometer) { + double distance; + double firstOdometer = first.getDouble(Position.KEY_ODOMETER); + double lastOdometer = last.getDouble(Position.KEY_ODOMETER); + + if (useOdometer && firstOdometer != 0.0 && lastOdometer != 0.0) { + distance = lastOdometer - firstOdometer; + } else { + distance = last.getDouble(Position.KEY_TOTAL_DISTANCE) - first.getDouble(Position.KEY_TOTAL_DISTANCE); + } + return distance; + } + } diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index f0c8c31b6..6de313a13 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -16,19 +16,8 @@ */ package org.traccar.reports; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; - import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; -import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -36,28 +25,34 @@ import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; -import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; public class EventsReportProvider { - private final PermissionsService permissionsService; - private final Storage storage; + private final ReportUtils reportUtils; @Inject - public EventsReportProvider(PermissionsService permissionsService, Storage storage) { - this.permissionsService = permissionsService; - this.storage = storage; + public EventsReportProvider(ReportUtils reportUtils) { + this.reportUtils = reportUtils; } public Collection getObjects( long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection events = Context.getDataManager().getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); @@ -65,9 +60,9 @@ public class EventsReportProvider { if (all || types.contains(event.getType())) { long geofenceId = event.getGeofenceId(); long maintenanceId = event.getMaintenanceId(); - if ((geofenceId == 0 || ReportUtils.getObject(storage, userId, Geofence.class, geofenceId) != null) + if ((geofenceId == 0 || reportUtils.getObject(userId, Geofence.class, geofenceId) != null) && (maintenanceId == 0 - || ReportUtils.getObject(storage, userId, Maintenance.class, maintenanceId) != null)) { + || reportUtils.getObject(userId, Maintenance.class, maintenanceId) != null)) { result.add(event); } } @@ -79,12 +74,12 @@ public class EventsReportProvider { public void getExcel( OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList devicesEvents = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection events = Context.getDataManager().getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); @@ -94,16 +89,14 @@ public class EventsReportProvider { long geofenceId = event.getGeofenceId(); long maintenanceId = event.getMaintenanceId(); if (geofenceId != 0) { - Geofence geofence = ReportUtils.getObject( - storage, userId, Geofence.class, geofenceId); + Geofence geofence = reportUtils.getObject(userId, Geofence.class, geofenceId); if (geofence != null) { geofenceNames.put(geofenceId, geofence.getName()); } else { iterator.remove(); } } else if (maintenanceId != 0) { - Maintenance maintenance = ReportUtils.getObject( - storage, userId, Maintenance.class, maintenanceId); + Maintenance maintenance = reportUtils.getObject(userId, Maintenance.class, maintenanceId); if (maintenance != null) { maintenanceNames.put(maintenanceId, maintenance.getName()); } else { @@ -130,15 +123,14 @@ public class EventsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { - var jxlsContext = ReportUtils.initializeContext( - permissionsService.getServer(), permissionsService.getUser(userId)); - jxlsContext.putVar("devices", devicesEvents); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("geofenceNames", geofenceNames); - jxlsContext.putVar("maintenanceNames", maintenanceNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + var context = reportUtils.initializeContext(userId); + context.putVar("devices", devicesEvents); + context.putVar("sheetNames", sheetNames); + context.putVar("geofenceNames", geofenceNames); + context.putVar("maintenanceNames", maintenanceNames); + context.putVar("from", from); + context.putVar("to", to); + reportUtils.processTemplateWithSheets(inputStream, outputStream, context); } } } diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index e20ba6885..136a154aa 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -16,17 +16,8 @@ */ package org.traccar.reports; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; -import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; @@ -35,21 +26,28 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; public class RouteReportProvider { - private final PermissionsService permissionsService; + private final ReportUtils reportUtils; @Inject - public RouteReportProvider(PermissionsService permissionsService) { - this.permissionsService = permissionsService; + public RouteReportProvider(ReportUtils reportUtils) { + this.reportUtils = reportUtils; } public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(Context.getDataManager().getPositions(deviceId, from, to)); } @@ -59,10 +57,10 @@ public class RouteReportProvider { public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection positions = Context.getDataManager() .getPositions(deviceId, from, to); @@ -82,13 +80,12 @@ public class RouteReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { - var jxlsContext = ReportUtils.initializeContext( - permissionsService.getServer(), permissionsService.getUser(userId)); - jxlsContext.putVar("devices", devicesRoutes); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + var context = reportUtils.initializeContext(userId); + context.putVar("devices", devicesRoutes); + context.putVar("sheetNames", sheetNames); + context.putVar("from", from); + context.putVar("to", to); + reportUtils.processTemplateWithSheets(inputStream, outputStream, context); } } } diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index b7896c423..807a6133b 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -14,65 +14,48 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.traccar.reports; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; -import org.traccar.Main; -import org.traccar.api.security.PermissionsService; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; -import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; public class StopsReportProvider { - private final PermissionsService permissionsService; - private final Storage storage; - private final TripsConfig tripsConfig; + private final ReportUtils reportUtils; @Inject - public StopsReportProvider(PermissionsService permissionsService, Storage storage, TripsConfig tripsConfig) { - this.permissionsService = permissionsService; - this.storage = storage; - this.tripsConfig = tripsConfig; + public StopsReportProvider(ReportUtils reportUtils) { + this.reportUtils = reportUtils; } private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - - IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); - DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - - return ReportUtils.detectTripsAndStops( - storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - tripsConfig, ignoreOdometer, StopReportItem.class); + return reportUtils.detectTripsAndStops( + Context.getDataManager().getPositions(deviceId, from, to), ignoreOdometer, StopReportItem.class); } public Collection getObjects( long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectStops(deviceId, from, to)); } @@ -82,10 +65,10 @@ public class StopsReportProvider { public void getExcel( OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection stops = detectStops(deviceId, from, to); DeviceReportSection deviceStops = new DeviceReportSection(); @@ -104,13 +87,12 @@ public class StopsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { - var jxlsContext = ReportUtils.initializeContext( - permissionsService.getServer(), permissionsService.getUser(userId)); - jxlsContext.putVar("devices", devicesStops); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + var context = reportUtils.initializeContext(userId); + context.putVar("devices", devicesStops); + context.putVar("sheetNames", sheetNames); + context.putVar("from", from); + context.putVar("to", to); + reportUtils.processTemplateWithSheets(inputStream, outputStream, context); } } diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 27dc5819d..28abe790b 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -16,19 +16,11 @@ */ package org.traccar.reports; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.Date; - import org.jxls.util.JxlsHelper; import org.traccar.Context; import org.traccar.api.security.PermissionsService; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; @@ -36,13 +28,23 @@ import org.traccar.reports.model.SummaryReportItem; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; public class SummaryReportProvider { + private final ReportUtils reportUtils; private final PermissionsService permissionsService; @Inject - public SummaryReportProvider(PermissionsService permissionsService) { + public SummaryReportProvider(ReportUtils reportUtils, PermissionsService permissionsService) { + this.reportUtils = reportUtils; this.permissionsService = permissionsService; } @@ -64,8 +66,8 @@ public class SummaryReportProvider { } boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - result.setDistance(ReportUtils.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); - result.setSpentFuel(ReportUtils.calculateFuel(firstPosition, previousPosition)); + result.setDistance(PositionUtil.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); + result.setSpentFuel(reportUtils.calculateFuel(firstPosition, previousPosition)); long durationMilliseconds; if (firstPosition.getAttributes().containsKey(Position.KEY_HOURS) @@ -134,9 +136,9 @@ public class SummaryReportProvider { public Collection getObjects( long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); for (SummaryReportItem summaryReport : deviceResults) { @@ -151,18 +153,17 @@ public class SummaryReportProvider { public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { - var jxlsContext = ReportUtils.initializeContext( - permissionsService.getServer(), permissionsService.getUser(userId)); - jxlsContext.putVar("summaries", summaries); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); + var context = reportUtils.initializeContext(userId); + context.putVar("summaries", summaries); + context.putVar("from", from); + context.putVar("to", to); JxlsHelper.getInstance().setUseFastFormulaProcessor(false) - .processTemplate(inputStream, outputStream, jxlsContext); + .processTemplate(inputStream, outputStream, context); } } } diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 0505baaa1..5e598cb50 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -16,42 +16,34 @@ */ package org.traccar.reports; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; - import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; import org.traccar.Main; -import org.traccar.api.security.PermissionsService; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; -import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; -import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; public class TripsReportProvider { - private final PermissionsService permissionsService; - private final Storage storage; - private final TripsConfig tripsConfig; + private final ReportUtils reportUtils; @Inject - public TripsReportProvider(PermissionsService permissionsService, Storage storage, TripsConfig tripsConfig) { - this.permissionsService = permissionsService; - this.storage = storage; - this.tripsConfig = tripsConfig; + public TripsReportProvider(ReportUtils reportUtils) { + this.reportUtils = reportUtils; } private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { @@ -61,16 +53,15 @@ public class TripsReportProvider { IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - return ReportUtils.detectTripsAndStops( - storage, identityManager, deviceManager, Context.getDataManager().getPositions(deviceId, from, to), - tripsConfig, ignoreOdometer, TripReportItem.class); + return reportUtils.detectTripsAndStops( + Context.getDataManager().getPositions(deviceId, from, to), ignoreOdometer, TripReportItem.class); } public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectTrips(deviceId, from, to)); } @@ -80,10 +71,10 @@ public class TripsReportProvider { public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { - ReportUtils.checkPeriodLimit(from, to); + reportUtils.checkPeriodLimit(from, to); ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { + for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection trips = detectTrips(deviceId, from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); @@ -102,13 +93,12 @@ public class TripsReportProvider { String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { - var jxlsContext = ReportUtils.initializeContext( - permissionsService.getServer(), permissionsService.getUser(userId)); - jxlsContext.putVar("devices", devicesTrips); - jxlsContext.putVar("sheetNames", sheetNames); - jxlsContext.putVar("from", from); - jxlsContext.putVar("to", to); - ReportUtils.processTemplateWithSheets(inputStream, outputStream, jxlsContext); + var context = reportUtils.initializeContext(userId); + context.putVar("devices", devicesTrips); + context.putVar("sheetNames", sheetNames); + context.putVar("from", from); + context.putVar("to", to); + reportUtils.processTemplateWithSheets(inputStream, outputStream, context); } } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 36d5c0fb1..706475241 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -26,28 +26,33 @@ import org.jxls.transform.Transformer; import org.jxls.transform.poi.PoiTransformer; import org.jxls.util.TransformerFactory; import org.traccar.Context; +import org.traccar.api.security.PermissionsService; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; +import org.traccar.geocoder.Geocoder; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; -import org.traccar.model.Server; -import org.traccar.model.User; -import org.traccar.session.DeviceState; import org.traccar.model.Driver; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.reports.model.BaseReportItem; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.TripReportItem; +import org.traccar.session.DeviceState; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.annotation.Nullable; +import javax.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -61,13 +66,31 @@ import java.util.List; import java.util.Locale; import java.util.Map; -public final class ReportUtils { - - private ReportUtils() { +public class ReportUtils { + + private final Config config; + private final Storage storage; + private final PermissionsService permissionsService; + private final IdentityManager identityManager; + private final DeviceManager deviceManager; + private final TripsConfig tripsConfig; + private final Geocoder geocoder; + + @Inject + public ReportUtils( + Config config, Storage storage, PermissionsService permissionsService, IdentityManager identityManager, + DeviceManager deviceManager, TripsConfig tripsConfig, @Nullable Geocoder geocoder) { + this.config = config; + this.storage = storage; + this.permissionsService = permissionsService; + this.identityManager = identityManager; + this.deviceManager = deviceManager; + this.tripsConfig = tripsConfig; + this.geocoder = geocoder; } - public static T getObject( - Storage storage, long userId, Class clazz, long objectId) throws StorageException, SecurityException { + public T getObject( + long userId, Class clazz, long objectId) throws StorageException, SecurityException { return storage.getObject(clazz, new Request( new Columns.Include("id"), new Condition.And( @@ -75,14 +98,14 @@ public final class ReportUtils { new Condition.Permission(User.class, userId, clazz)))); } - public static void checkPeriodLimit(Date from, Date to) { - long limit = Context.getConfig().getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; + public void checkPeriodLimit(Date from, Date to) { + long limit = config.getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; if (limit > 0 && to.getTime() - from.getTime() > limit) { throw new IllegalArgumentException("Time period exceeds the limit"); } } - public static Collection getDeviceList(Collection deviceIds, Collection groupIds) { + public Collection getDeviceList(Collection deviceIds, Collection groupIds) { Collection result = new LinkedHashSet<>(deviceIds); for (long groupId : groupIds) { result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); @@ -90,26 +113,7 @@ public final class ReportUtils { return result; } - public static double calculateDistance(Position firstPosition, Position lastPosition) { - return calculateDistance(firstPosition, lastPosition, true); - } - - public static double calculateDistance(Position firstPosition, Position lastPosition, boolean useOdometer) { - double distance = 0.0; - double firstOdometer = firstPosition.getDouble(Position.KEY_ODOMETER); - double lastOdometer = lastPosition.getDouble(Position.KEY_ODOMETER); - - if (useOdometer && firstOdometer != 0.0 && lastOdometer != 0.0) { - distance = lastOdometer - firstOdometer; - } else if (firstPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE) - && lastPosition.getAttributes().containsKey(Position.KEY_TOTAL_DISTANCE)) { - distance = lastPosition.getDouble(Position.KEY_TOTAL_DISTANCE) - - firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE); - } - return distance; - } - - public static double calculateFuel(Position firstPosition, Position lastPosition) { + public double calculateFuel(Position firstPosition, Position lastPosition) { if (firstPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null && lastPosition.getAttributes().get(Position.KEY_FUEL_LEVEL) != null) { @@ -121,7 +125,7 @@ public final class ReportUtils { return 0; } - public static String findDriver(Position firstPosition, Position lastPosition) { + public String findDriver(Position firstPosition, Position lastPosition) { if (firstPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { return firstPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); } else if (lastPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { @@ -130,7 +134,7 @@ public final class ReportUtils { return null; } - public static String findDriverName(Storage storage, String driverUniqueId) throws StorageException { + public String findDriverName(String driverUniqueId) throws StorageException { if (driverUniqueId != null) { Driver driver = storage.getObject(Driver.class, new Request( new Columns.All(), @@ -142,28 +146,29 @@ public final class ReportUtils { return null; } - public static org.jxls.common.Context initializeContext(Server server, User user) { - org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext(); - jxlsContext.putVar("distanceUnit", UserUtil.getDistanceUnit(server, user)); - jxlsContext.putVar("speedUnit", UserUtil.getSpeedUnit(server, user)); - jxlsContext.putVar("volumeUnit", UserUtil.getVolumeUnit(server, user)); - jxlsContext.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); - jxlsContext.putVar("dateTool", new DateTool()); - jxlsContext.putVar("numberTool", new NumberTool()); - jxlsContext.putVar("timezone", UserUtil.getTimezone(server, user)); - jxlsContext.putVar("locale", Locale.getDefault()); - jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); - return jxlsContext; + public org.jxls.common.Context initializeContext(long userId) throws StorageException { + var server = permissionsService.getServer(); + var user = permissionsService.getUser(userId); + var context = PoiTransformer.createInitialContext(); + context.putVar("distanceUnit", UserUtil.getDistanceUnit(server, user)); + context.putVar("speedUnit", UserUtil.getSpeedUnit(server, user)); + context.putVar("volumeUnit", UserUtil.getVolumeUnit(server, user)); + context.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); + context.putVar("dateTool", new DateTool()); + context.putVar("numberTool", new NumberTool()); + context.putVar("timezone", UserUtil.getTimezone(server, user)); + context.putVar("locale", Locale.getDefault()); + context.putVar("bracketsRegex", "[\\{\\}\"]"); + return context; } - public static void processTemplateWithSheets( - InputStream templateStream, OutputStream targetStream, - org.jxls.common.Context jxlsContext) throws IOException { + public void processTemplateWithSheets( + InputStream templateStream, OutputStream targetStream, org.jxls.common.Context context) throws IOException { Transformer transformer = TransformerFactory.createTransformer(templateStream, targetStream); List xlsAreas = new XlsCommentAreaBuilder(transformer).build(); for (Area xlsArea : xlsAreas) { - xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), jxlsContext); + xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), context); xlsArea.setFormulaProcessor(new StandardFormulaProcessor()); xlsArea.processFormulas(); } @@ -171,9 +176,9 @@ public final class ReportUtils { transformer.write(); } - private static TripReportItem calculateTrip( - Storage storage, IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer) throws StorageException { + private TripReportItem calculateTrip( + ArrayList positions, int startIndex, int endIndex, + boolean ignoreOdometer) throws StorageException { Position startTrip = positions.get(startIndex); Position endTrip = positions.get(endIndex); @@ -198,9 +203,8 @@ public final class ReportUtils { trip.setStartLon(startTrip.getLongitude()); trip.setStartTime(startTrip.getFixTime()); String startAddress = startTrip.getAddress(); - if (startAddress == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - startAddress = Context.getGeocoder().getAddress(startTrip.getLatitude(), startTrip.getLongitude(), null); + if (startAddress == null && geocoder != null && config.getBoolean(Keys.GEOCODER_ON_REQUEST)) { + startAddress = geocoder.getAddress(startTrip.getLatitude(), startTrip.getLongitude(), null); } trip.setStartAddress(startAddress); @@ -209,13 +213,12 @@ public final class ReportUtils { trip.setEndLon(endTrip.getLongitude()); trip.setEndTime(endTrip.getFixTime()); String endAddress = endTrip.getAddress(); - if (endAddress == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - endAddress = Context.getGeocoder().getAddress(endTrip.getLatitude(), endTrip.getLongitude(), null); + if (endAddress == null && geocoder != null && config.getBoolean(Keys.GEOCODER_ON_REQUEST)) { + endAddress = geocoder.getAddress(endTrip.getLatitude(), endTrip.getLongitude(), null); } trip.setEndAddress(endAddress); - trip.setDistance(calculateDistance(startTrip, endTrip, !ignoreOdometer)); + trip.setDistance(PositionUtil.calculateDistance(startTrip, endTrip, !ignoreOdometer)); trip.setDuration(tripDuration); if (tripDuration > 0) { trip.setAverageSpeed(UnitsConverter.knotsFromMps(trip.getDistance() * 1000 / tripDuration)); @@ -224,7 +227,7 @@ public final class ReportUtils { trip.setSpentFuel(calculateFuel(startTrip, endTrip)); trip.setDriverUniqueId(findDriver(startTrip, endTrip)); - trip.setDriverName(findDriverName(storage, trip.getDriverUniqueId())); + trip.setDriverName(findDriverName(trip.getDriverUniqueId())); if (!ignoreOdometer && startTrip.getDouble(Position.KEY_ODOMETER) != 0 @@ -239,9 +242,8 @@ public final class ReportUtils { return trip; } - private static StopReportItem calculateStop( - IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer) { + private StopReportItem calculateStop( + ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); @@ -257,9 +259,8 @@ public final class ReportUtils { stop.setLongitude(startStop.getLongitude()); stop.setStartTime(startStop.getFixTime()); String address = startStop.getAddress(); - if (address == null && Context.getGeocoder() != null - && Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST)) { - address = Context.getGeocoder().getAddress(stop.getLatitude(), stop.getLongitude(), null); + if (address == null && geocoder != null && config.getBoolean(Keys.GEOCODER_ON_REQUEST)) { + address = geocoder.getAddress(stop.getLatitude(), stop.getLongitude(), null); } stop.setAddress(address); @@ -288,18 +289,19 @@ public final class ReportUtils { } - private static T calculateTripOrStop( - Storage storage, IdentityManager identityManager, ArrayList positions, - int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) throws StorageException { + @SuppressWarnings("unchecked") + private T calculateTripOrStop( + ArrayList positions, int startIndex, int endIndex, + boolean ignoreOdometer, Class reportClass) throws StorageException { if (reportClass.equals(TripReportItem.class)) { - return (T) calculateTrip(storage, identityManager, positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateTrip(positions, startIndex, endIndex, ignoreOdometer); } else { - return (T) calculateStop(identityManager, positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateStop(positions, startIndex, endIndex, ignoreOdometer); } } - private static boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig) { + private boolean isMoving(ArrayList positions, int index, TripsConfig tripsConfig) { if (tripsConfig.getMinimalNoDataDuration() > 0) { boolean beforeGap = index < positions.size() - 1 && positions.get(index + 1).getFixTime().getTime() - positions.get(index).getFixTime().getTime() @@ -319,17 +321,16 @@ public final class ReportUtils { } } - public static Collection detectTripsAndStops( - Storage storage, IdentityManager identityManager, DeviceManager deviceManager, - Collection positionCollection, - TripsConfig tripsConfig, boolean ignoreOdometer, Class reportClass) throws StorageException { + public Collection detectTripsAndStops( + Collection positionCollection, boolean ignoreOdometer, + Class reportClass) throws StorageException { Collection result = new ArrayList<>(); ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); - MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); + MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; @@ -355,15 +356,15 @@ public final class ReportUtils { } if (startEventIndex != -1 && startNoEventIndex != -1 && event != null && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop(storage, identityManager, positions, - startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); + result.add(calculateTripOrStop( + positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); startEventIndex = -1; } } if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - result.add(calculateTripOrStop(storage, identityManager, positions, - startEventIndex, startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1, - ignoreOdometer, reportClass)); + int endIndex = startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1; + result.add(calculateTripOrStop( + positions, startEventIndex, endIndex, ignoreOdometer, reportClass)); } } diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 9b287a0fd..92bfdae1c 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -2,7 +2,11 @@ package org.traccar.reports; import org.junit.Test; import org.traccar.BaseTest; +import org.traccar.api.security.PermissionsService; +import org.traccar.config.Config; +import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; @@ -63,20 +67,23 @@ public class ReportUtilsTest extends BaseTest { startPosition.set(Position.KEY_TOTAL_DISTANCE, 500.0); Position endPosition = new Position(); endPosition.set(Position.KEY_TOTAL_DISTANCE, 700.0); - assertEquals(ReportUtils.calculateDistance(startPosition, endPosition), 200.0, 10); + assertEquals(PositionUtil.calculateDistance(startPosition, endPosition, true), 200.0, 10); startPosition.set(Position.KEY_ODOMETER, 50000); endPosition.set(Position.KEY_ODOMETER, 51000); - assertEquals(ReportUtils.calculateDistance(startPosition, endPosition), 1000.0, 10); + assertEquals(PositionUtil.calculateDistance(startPosition, endPosition, true), 1000.0, 10); } @Test public void testCalculateSpentFuel() { + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), mock(TripsConfig.class), null); Position startPosition = new Position(); Position endPosition = new Position(); - assertEquals(ReportUtils.calculateFuel(startPosition, endPosition), 0.0, 0.01); + assertEquals(reportUtils.calculateFuel(startPosition, endPosition), 0.0, 0.01); startPosition.set(Position.KEY_FUEL_LEVEL, 0.7); endPosition.set(Position.KEY_FUEL_LEVEL, 0.5); - assertEquals(ReportUtils.calculateFuel(startPosition, endPosition), 0.2, 0.01); + assertEquals(reportUtils.calculateFuel(startPosition, endPosition), 0.2, 0.01); } @Test @@ -93,9 +100,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:07:00.000", 0, 3000)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection trips = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -109,8 +118,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -147,9 +155,11 @@ public class ReportUtilsTest extends BaseTest { data.get(5).set(Position.KEY_IGNITION, false); TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection trips = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -163,8 +173,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - trips = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -178,8 +187,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -218,9 +226,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:11:00.000", 0, 7000)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection trips = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -234,8 +244,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -268,9 +277,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:05:00.000", 0, 0)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection result = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -295,9 +306,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:05:00.000", 2, 0)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection result = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -322,9 +335,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:05:00.000", 0, 0)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection result = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -349,9 +364,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:05:00.000", 5, 0)); TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection result = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -372,9 +389,11 @@ public class ReportUtilsTest extends BaseTest { position("2016-01-01 00:25:00.000", 5, 900)); TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); + ReportUtils reportUtils = new ReportUtils( + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), + mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); - Collection trips = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -388,8 +407,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - Collection stops = ReportUtils.detectTripsAndStops( - mock(Storage.class), mockIdentityManager(), null, data, tripsConfig, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From fe61a79b37a2de3bc435890e5cca43ac05fc598c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Jun 2022 08:19:27 -0700 Subject: Full injection for notificators --- .../traccar/notificators/NotificatorFirebase.java | 39 ++++++----------- .../traccar/notificators/NotificatorPushover.java | 50 +++++++-------------- .../traccar/notificators/NotificatorTelegram.java | 51 ++++++++-------------- .../traccar/notificators/NotificatorTraccar.java | 15 ++++--- .../org/traccar/notificators/NotificatorWeb.java | 20 ++++++--- 5 files changed, 72 insertions(+), 103 deletions(-) diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index cafd2237d..3f1667568 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -17,24 +17,22 @@ package org.traccar.notificators; import com.fasterxml.jackson.annotation.JsonProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -import org.traccar.notification.NotificationMessage; import org.traccar.notification.NotificationFormatter; import org.traccar.session.cache.CacheManager; +import javax.inject.Inject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; public class NotificatorFirebase implements Notificator { - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorFirebase.class); + private final CacheManager cacheManager; + private final Client client; private final String url; private final String key; @@ -55,13 +53,16 @@ public class NotificatorFirebase implements Notificator { private Notification notification; } - public NotificatorFirebase() { + @Inject + public NotificatorFirebase(Config config, CacheManager cacheManager, Client client) { this( - "https://fcm.googleapis.com/fcm/send", - Context.getConfig().getString(Keys.NOTIFICATOR_FIREBASE_KEY)); + cacheManager, client, "https://fcm.googleapis.com/fcm/send", + config.getString(Keys.NOTIFICATOR_FIREBASE_KEY)); } - protected NotificatorFirebase(String url, String key) { + protected NotificatorFirebase(CacheManager cacheManager, Client client, String url, String key) { + this.cacheManager = cacheManager; + this.client = client; this.url = url; this.key = key; } @@ -70,8 +71,7 @@ public class NotificatorFirebase implements Notificator { public void send(User user, Event event, Position position) { if (user.getAttributes().containsKey("notificationTokens")) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); + var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); Notification notification = new Notification(); notification.title = shortMessage.getSubject(); @@ -82,18 +82,7 @@ public class NotificatorFirebase implements Notificator { message.tokens = user.getString("notificationTokens").split("[, ]"); message.notification = notification; - Context.getClient().target(url).request() - .header("Authorization", "key=" + key) - .async().post(Entity.json(message), new InvocationCallback() { - @Override - public void completed(Object o) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Firebase notification error", throwable); - } - }); + client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 70c1a6cdc..2ac489dd6 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -16,24 +16,22 @@ package org.traccar.notificators; import com.fasterxml.jackson.annotation.JsonProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.NotificationMessage; import org.traccar.session.cache.CacheManager; +import javax.inject.Inject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; public class NotificatorPushover implements Notificator { - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorPushover.class); + private final CacheManager cacheManager; + private final Client client; private final String url; private final String token; @@ -52,33 +50,27 @@ public class NotificatorPushover implements Notificator { private String message; } - public NotificatorPushover() { + @Inject + public NotificatorPushover(Config config, CacheManager cacheManager, Client client) { + this.cacheManager = cacheManager; + this.client = client; url = "https://api.pushover.net/1/messages.json"; - token = Context.getConfig().getString(Keys.NOTIFICATOR_PUSHOVER_TOKEN); - user = Context.getConfig().getString(Keys.NOTIFICATOR_PUSHOVER_USER); + token = config.getString(Keys.NOTIFICATOR_PUSHOVER_TOKEN); + user = config.getString(Keys.NOTIFICATOR_PUSHOVER_USER); + if (token == null || user == null) { + throw new RuntimeException("Pushover token or user missing"); + } } @Override public void send(User user, Event event, Position position) { String device = ""; - if (user.getAttributes().containsKey("notificator.pushover.device")) { device = user.getString("notificator.pushover.device").replaceAll(" *, *", ","); } - if (token == null) { - LOGGER.warn("Pushover token not found"); - return; - } - - if (this.user == null) { - LOGGER.warn("Pushover user not found"); - return; - } - - NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); + var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); Message message = new Message(); message.token = token; @@ -87,17 +79,7 @@ public class NotificatorPushover implements Notificator { message.title = shortMessage.getSubject(); message.message = shortMessage.getBody(); - Context.getClient().target(url).request() - .async().post(Entity.json(message), new InvocationCallback() { - @Override - public void completed(Object o) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Pushover API error", throwable); - } - }); + client.target(url).request().post(Entity.json(message)).close(); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 0ed53ac4c..1dccf2c04 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -17,24 +17,22 @@ package org.traccar.notificators; import com.fasterxml.jackson.annotation.JsonProperty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; -import org.traccar.model.User; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.NotificationMessage; import org.traccar.session.cache.CacheManager; +import javax.inject.Inject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; -import javax.ws.rs.client.InvocationCallback; public class NotificatorTelegram implements Notificator { - private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorTelegram.class); + private final CacheManager cacheManager; + private final Client client; private final String urlSendText; private final String urlSendLocation; @@ -63,29 +61,16 @@ public class NotificatorTelegram implements Notificator { private int bearing; } - public NotificatorTelegram() { + @Inject + public NotificatorTelegram(Config config, CacheManager cacheManager, Client client) { + this.cacheManager = cacheManager; + this.client = client; urlSendText = String.format( - "https://api.telegram.org/bot%s/sendMessage", - Context.getConfig().getString(Keys.NOTIFICATOR_TELEGRAM_KEY)); + "https://api.telegram.org/bot%s/sendMessage", config.getString(Keys.NOTIFICATOR_TELEGRAM_KEY)); urlSendLocation = String.format( - "https://api.telegram.org/bot%s/sendLocation", - Context.getConfig().getString(Keys.NOTIFICATOR_TELEGRAM_KEY)); - chatId = Context.getConfig().getString(Keys.NOTIFICATOR_TELEGRAM_CHAT_ID); - sendLocation = Context.getConfig().getBoolean(Keys.NOTIFICATOR_TELEGRAM_SEND_LOCATION); - } - - private void executeRequest(String url, Object message) { - Context.getClient().target(url).request() - .async().post(Entity.json(message), new InvocationCallback() { - @Override - public void completed(Object o) { - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Telegram API error", throwable); - } - }); + "https://api.telegram.org/bot%s/sendLocation", config.getString(Keys.NOTIFICATOR_TELEGRAM_KEY)); + chatId = config.getString(Keys.NOTIFICATOR_TELEGRAM_CHAT_ID); + sendLocation = config.getBoolean(Keys.NOTIFICATOR_TELEGRAM_SEND_LOCATION); } private LocationMessage createLocationMessage(String messageChatId, Position position) { @@ -100,8 +85,7 @@ public class NotificatorTelegram implements Notificator { @Override public void send(User user, Event event, Position position) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); + var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); @@ -109,9 +93,10 @@ public class NotificatorTelegram implements Notificator { message.chatId = chatId; } message.text = shortMessage.getBody(); - executeRequest(urlSendText, message); + client.target(urlSendText).request().post(Entity.json(message)).close(); if (sendLocation && position != null) { - executeRequest(urlSendLocation, createLocationMessage(message.chatId, position)); + client.target(urlSendLocation).request().post( + Entity.json(createLocationMessage(message.chatId, position))).close(); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 5bcd18b5e..0827567ae 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,20 @@ */ package org.traccar.notificators; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.session.cache.CacheManager; + +import javax.inject.Inject; +import javax.ws.rs.client.Client; public class NotificatorTraccar extends NotificatorFirebase { - public NotificatorTraccar() { + @Inject + public NotificatorTraccar(Config config, CacheManager cacheManager, Client client) { super( - "https://www.traccar.org/push/", - Context.getConfig().getString(Keys.NOTIFICATOR_TRACCAR_KEY)); + cacheManager, client, "https://www.traccar.org/push/", + config.getString(Keys.NOTIFICATOR_TRACCAR_KEY)); } } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index e19a94c1d..402f7a9f0 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -16,17 +16,26 @@ */ package org.traccar.notificators; -import org.traccar.Context; -import org.traccar.Main; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.NotificationMessage; +import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; +import javax.inject.Inject; + public final class NotificatorWeb implements Notificator { + private final ConnectionManager connectionManager; + private final CacheManager cacheManager; + + @Inject + public NotificatorWeb(ConnectionManager connectionManager, CacheManager cacheManager) { + this.connectionManager = connectionManager; + this.cacheManager = cacheManager; + } + @Override public void send(User user, Event event, Position position) { @@ -40,11 +49,10 @@ public final class NotificatorWeb implements Notificator { copy.setMaintenanceId(event.getMaintenanceId()); copy.getAttributes().putAll(event.getAttributes()); - NotificationMessage message = NotificationFormatter.formatMessage( - Main.getInjector().getInstance(CacheManager.class), user, event, position, "short"); + var message = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); copy.set("message", message.getBody()); - Context.getConnectionManager().updateEvent(user.getId(), copy); + connectionManager.updateEvent(user.getId(), copy); } } -- cgit v1.2.3 From 18fa5d9b7a234638183cd773dcb49987d51cc381 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Jun 2022 09:43:31 -0700 Subject: Special watch prefix --- src/main/java/org/traccar/protocol/WatchProtocolEncoder.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java index f1904ea4d..14ebe2852 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java @@ -67,6 +67,9 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin if (decoder != null) { hasIndex = decoder.getHasIndex(); manufacturer = decoder.getManufacturer(); + if (manufacturer.equals("3G")) { + manufacturer = "SG"; + } } } -- cgit v1.2.3 From 7d9eb1d2993ddc33523645ed4cce29729b0163ff Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 10 Jun 2022 18:08:40 -0700 Subject: GoSafe G1A additional data --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 6 +++++- src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 00093c978..b891bc388 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -123,7 +123,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { || BitUtil.check(value, 10) || BitUtil.check(value, 11)) { return Position.ALARM_FAULT; } - if (BitUtil.check(value, 7)) { + if (BitUtil.check(value, 7) || BitUtil.check(value, 18)) { return Position.ALARM_LOW_BATTERY; } if (BitUtil.check(value, 8)) { @@ -376,6 +376,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); position.set(Position.KEY_BLOCKED, BitUtil.check(status, 10)); + position.set(Position.KEY_CHARGE, BitUtil.check(status, 26)); position.setValid(BitUtil.check(status, 1)); @@ -540,6 +541,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x00CE: position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); break; + case 0xE1: + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + break; default: buf.skipBytes(extendedLength - 2); break; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 0b36b8f4d..49622745f 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "7e020000340551231425560568000000000400000201618a9706c320e100410000002722060816261501040000015d300115310105eb0a000300e164000300e301957e"), + Position.KEY_BATTERY_LEVEL, 100); + verifyNull(decoder, buffer( "(794104004140,1,001,BASE,2,TIME)")); -- cgit v1.2.3 From 8177c9b5ebd1a337fa97b93a31e8772f7b21c356 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 07:21:43 -0700 Subject: Remove object mapper usage --- .../org/traccar/protocol/StbProtocolDecoder.java | 33 +++++----------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java index c07337fc5..641359bfd 100644 --- a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,12 @@ */ package org.traccar.protocol; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.model.Position; +import org.traccar.session.DeviceSession; import javax.json.Json; import javax.json.JsonObject; @@ -42,29 +39,13 @@ public class StbProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_PROPERTY = 310; public static final int MSG_ALARM = 410; - public static class Response { - @JsonProperty("msgType") - private int type; - @JsonProperty("devId") - private String deviceId; - @JsonProperty("result") - private int result; - @JsonProperty("txnNo") - private String transaction; - } - private void sendResponse( - Channel channel, SocketAddress remoteAddress, int type, String deviceId, JsonObject root) - throws JsonProcessingException { - - Response response = new Response(); - response.type = type + 1; - response.deviceId = deviceId; - response.result = 1; - response.transaction = root.getString("txnNo"); + Channel channel, SocketAddress remoteAddress, int type, String deviceId, JsonObject root) { + String response = String.format( + "{ \"msgType\": %d, \"devId\": \"%s\", \"result\": 1, \"txnNo\": \"%s\" }", + type + 1, deviceId, root.getString("txnNo")); if (channel != null) { - channel.writeAndFlush(new NetworkMessage( - Context.getObjectMapper().writeValueAsString(response), remoteAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } -- cgit v1.2.3 From 5b269c0e309b70866ad167fb148eafcbad5a8b26 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 07:27:19 -0700 Subject: Inject event forwarder --- src/main/java/org/traccar/Context.java | 11 +---------- src/main/java/org/traccar/MainModule.java | 9 +++++++++ .../org/traccar/database/NotificationManager.java | 20 +++++++++----------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 471416926..95ff2eddb 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -127,12 +127,6 @@ public final class Context { return client; } - private static EventForwarder eventForwarder; - - public static EventForwarder getEventForwarder() { - return eventForwarder; - } - private static class ObjectMapperContextResolver implements ContextResolver { @Override @@ -181,10 +175,6 @@ public final class Context { initEventsModule(); - if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - eventForwarder = new EventForwarder(config); - } - } private static void initEventsModule() { @@ -192,6 +182,7 @@ public final class Context { notificationManager = new NotificationManager( dataManager, Main.getInjector().getInstance(CacheManager.class), + Main.getInjector().getInstance(EventForwarder.class), Main.getInjector().getInstance(NotificatorManager.class), Main.getInjector().getInstance(Geocoder.class)); Properties velocityProperties = new Properties(); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index f6621a18e..e3f693444 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -25,6 +25,7 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; +import org.traccar.notification.EventForwarder; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; @@ -269,4 +270,12 @@ public class MainModule extends AbstractModule { return null; } + @Provides + public static EventForwarder provideEventForwarder(Config config) { + if (config.hasKey(Keys.EVENT_FORWARD_URL)) { + return new EventForwarder(config); + } + return null; + } + } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 1f4a48ac0..3c87aacb2 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,6 +37,7 @@ import org.traccar.model.Notification; import org.traccar.model.Position; import org.traccar.model.Typed; import org.traccar.model.User; +import org.traccar.notification.EventForwarder; import org.traccar.notification.MessageException; import org.traccar.notification.NotificatorManager; import org.traccar.session.cache.CacheManager; @@ -49,16 +50,18 @@ public class NotificationManager extends ExtendedObjectManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); private final CacheManager cacheManager; + private final EventForwarder eventForwarder; private final NotificatorManager notificatorManager; private final Geocoder geocoder; private final boolean geocodeOnRequest; public NotificationManager( - DataManager dataManager, CacheManager cacheManager, + DataManager dataManager, CacheManager cacheManager, @Nullable EventForwarder eventForwarder, NotificatorManager notificatorManager, @Nullable Geocoder geocoder) { super(dataManager, Notification.class); this.cacheManager = cacheManager; + this.eventForwarder = eventForwarder; this.notificatorManager = notificatorManager; this.geocoder = geocoder; geocodeOnRequest = Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST); @@ -88,14 +91,9 @@ public class NotificationManager extends ExtendedObjectManager { long deviceId = event.getDeviceId(); Set users = Context.getPermissionsManager().getDeviceUsers(deviceId); - Set usersToForward = null; - if (Context.getEventForwarder() != null) { - usersToForward = new HashSet<>(); - } + Set usersToForward = new HashSet<>(); for (long userId : users) { - if (usersToForward != null) { - usersToForward.add(userId); - } + usersToForward.add(userId); final Set notificators = new HashSet<>(); for (long notificationId : getEffectiveNotifications(userId, deviceId, event.getEventTime())) { Notification notification = getById(notificationId); @@ -131,8 +129,8 @@ public class NotificationManager extends ExtendedObjectManager { } }).start(); } - if (Context.getEventForwarder() != null) { - Context.getEventForwarder().forwardEvent(event, position, usersToForward); + if (eventForwarder != null) { + eventForwarder.forwardEvent(event, position, usersToForward); } } -- cgit v1.2.3 From a401b40ee3b69d5679031a1e1d7287a0a56f4160 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 08:28:41 -0700 Subject: Inject velocity engine --- gradle/checkstyle.xml | 4 ++- src/main/java/org/traccar/Context.java | 30 ------------------ src/main/java/org/traccar/MainModule.java | 29 +++++++++++++++++ .../org/traccar/api/resource/PasswordResource.java | 13 ++++---- src/main/java/org/traccar/config/Keys.java | 17 ++++++++++ .../notification/NotificationFormatter.java | 20 ++++++++---- .../notification/TextTemplateFormatter.java | 23 ++++++++------ .../traccar/notificators/NotificatorFirebase.java | 14 ++++---- .../org/traccar/notificators/NotificatorMail.java | 11 +++---- .../traccar/notificators/NotificatorPushover.java | 9 +++--- .../org/traccar/notificators/NotificatorSms.java | 12 +++---- .../traccar/notificators/NotificatorTelegram.java | 9 +++--- .../traccar/notificators/NotificatorTraccar.java | 6 ++-- .../org/traccar/notificators/NotificatorWeb.java | 9 +++--- .../org/traccar/reports/common/ReportUtils.java | 8 +++-- .../java/org/traccar/reports/ReportUtilsTest.java | 37 +++++++++++----------- 16 files changed, 139 insertions(+), 112 deletions(-) diff --git a/gradle/checkstyle.xml b/gradle/checkstyle.xml index 6cff6ffa5..a6a6f0ff7 100644 --- a/gradle/checkstyle.xml +++ b/gradle/checkstyle.xml @@ -79,7 +79,9 @@ - + + + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 95ff2eddb..627acd4e2 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -18,8 +18,6 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr353.JSR353Module; -import org.apache.velocity.app.VelocityEngine; -import org.eclipse.jetty.util.URIUtil; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; @@ -46,9 +44,6 @@ import org.traccar.session.cache.CacheManager; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.ext.ContextResolver; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Properties; public final class Context { @@ -115,12 +110,6 @@ public final class Context { return notificationManager; } - private static VelocityEngine velocityEngine; - - public static VelocityEngine getVelocityEngine() { - return velocityEngine; - } - private static Client client = ClientBuilder.newClient(); public static Client getClient() { @@ -185,25 +174,6 @@ public final class Context { Main.getInjector().getInstance(EventForwarder.class), Main.getInjector().getInstance(NotificatorManager.class), Main.getInjector().getInstance(Geocoder.class)); - Properties velocityProperties = new Properties(); - velocityProperties.setProperty("file.resource.loader.path", - Context.getConfig().getString("templates.rootPath", "templates") + "/"); - velocityProperties.setProperty("runtime.log.logsystem.class", - "org.apache.velocity.runtime.log.NullLogChute"); - - String address; - try { - address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); - } catch (UnknownHostException e) { - address = "localhost"; - } - - String webUrl = URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", ""); - webUrl = Context.getConfig().getString("web.url", webUrl); - velocityProperties.setProperty("web.url", webUrl); - - velocityEngine = new VelocityEngine(); - velocityEngine.init(velocityProperties); } public static BaseObjectManager getManager(Class clazz) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index e3f693444..a6f983a6b 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -21,6 +21,9 @@ import com.google.inject.Provides; import com.google.inject.Scopes; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.runtime.log.NullLogChute; +import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -70,6 +73,9 @@ import javax.annotation.Nullable; import javax.inject.Singleton; import javax.ws.rs.client.Client; import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Properties; public class MainModule extends AbstractModule { @@ -278,4 +284,27 @@ public class MainModule extends AbstractModule { return null; } + @Singleton + @Provides + public static VelocityEngine provideVelocityEngine(Config config) { + Properties properties = new Properties(); + properties.setProperty("file.resource.loader.path", config.getString(Keys.TEMPLATES_ROOT) + "/"); + properties.setProperty("runtime.log.logsystem.class", NullLogChute.class.getName()); + + String address; + try { + address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (UnknownHostException e) { + address = "localhost"; + } + + String url = config.getString( + Keys.WEB_URL, URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", "")); + properties.setProperty("web.url", url); + + VelocityEngine velocityEngine = new VelocityEngine(); + velocityEngine.init(properties); + return velocityEngine; + } + } diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 7df25c264..c7244f41c 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,10 @@ */ package org.traccar.api.resource; -import org.apache.velocity.VelocityContext; import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.database.MailManager; import org.traccar.model.User; -import org.traccar.notification.NotificationMessage; import org.traccar.notification.TextTemplateFormatter; import org.traccar.storage.StorageException; @@ -46,6 +44,9 @@ public class PasswordResource extends BaseResource { @Inject private MailManager mailManager; + @Inject + private TextTemplateFormatter textTemplateFormatter; + @Path("reset") @PermitAll @POST @@ -56,11 +57,9 @@ public class PasswordResource extends BaseResource { String token = UUID.randomUUID().toString().replaceAll("-", ""); user.set(PASSWORD_RESET_TOKEN, token); Context.getUsersManager().updateItem(user); - VelocityContext velocityContext = TextTemplateFormatter.prepareContext( - permissionsService.getServer(), user); + var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); velocityContext.put("token", token); - NotificationMessage fullMessage = - TextTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); + var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); break; } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index d53245c65..82afe048b 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -687,6 +687,14 @@ public final class Keys { "commands.queueing", Collections.singletonList(KeyType.GLOBAL)); + /** + * Root folder for all template files. + */ + public static final ConfigKey TEMPLATES_ROOT = new ConfigKey<>( + "templates.root", + Collections.singletonList(KeyType.GLOBAL), + "templates"); + /** * SMS API service full URL. Enables SMS commands and notifications. */ @@ -1245,6 +1253,15 @@ public final class Keys { "web.persistSession", Collections.singletonList(KeyType.GLOBAL)); + /** + * Public URL for the web app. Used for notification and report link. + * + * If not provided, Traccar will attempt to get a URL from the server IP address, but it might be a local address. + */ + public static final ConfigKey WEB_URL = new ConfigKey<>( + "web.url", + Collections.singletonList(KeyType.GLOBAL)); + /** * Output logging to the standard terminal output instead of a log file. */ diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index 2d3b90412..fa244d9b4 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -27,18 +27,26 @@ import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.session.cache.CacheManager; -public final class NotificationFormatter { +import javax.inject.Inject; - private NotificationFormatter() { +public class NotificationFormatter { + + private final CacheManager cacheManager; + private final TextTemplateFormatter textTemplateFormatter; + + @Inject + public NotificationFormatter( + CacheManager cacheManager, TextTemplateFormatter textTemplateFormatter) { + this.cacheManager = cacheManager; + this.textTemplateFormatter = textTemplateFormatter; } - public static NotificationMessage formatMessage( - CacheManager cacheManager, User user, Event event, Position position, String templatePath) { + public NotificationMessage formatMessage(User user, Event event, Position position, String templatePath) { Server server = cacheManager.getServer(); Device device = cacheManager.getObject(Device.class, event.getDeviceId()); - VelocityContext velocityContext = TextTemplateFormatter.prepareContext(server, user); + VelocityContext velocityContext = textTemplateFormatter.prepareContext(server, user); velocityContext.put("device", device); velocityContext.put("event", event); @@ -59,7 +67,7 @@ public final class NotificationFormatter { velocityContext.put("driver", cacheManager.findDriverByUniqueId(device.getId(), driverUniqueId)); } - return TextTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); + return textTemplateFormatter.formatMessage(velocityContext, event.getType(), templatePath); } } diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index 9072ec89e..bca18f53c 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -17,29 +17,34 @@ package org.traccar.notification; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.tools.generic.DateTool; import org.apache.velocity.tools.generic.NumberTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.helper.model.UserUtil; import org.traccar.model.Server; import org.traccar.model.User; +import javax.inject.Inject; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.util.Locale; -public final class TextTemplateFormatter { +public class TextTemplateFormatter { private static final Logger LOGGER = LoggerFactory.getLogger(TextTemplateFormatter.class); - private TextTemplateFormatter() { + private final VelocityEngine velocityEngine; + + @Inject + public TextTemplateFormatter(VelocityEngine velocityEngine) { + this.velocityEngine = velocityEngine; } - public static VelocityContext prepareContext(Server server, User user) { + public VelocityContext prepareContext(Server server, User user) { VelocityContext velocityContext = new VelocityContext(); @@ -48,7 +53,7 @@ public final class TextTemplateFormatter { velocityContext.put("timezone", UserUtil.getTimezone(server, user)); } - velocityContext.put("webUrl", Context.getVelocityEngine().getProperty("web.url")); + velocityContext.put("webUrl", velocityEngine.getProperty("web.url")); velocityContext.put("dateTool", new DateTool()); velocityContext.put("numberTool", new NumberTool()); velocityContext.put("locale", Locale.getDefault()); @@ -56,23 +61,23 @@ public final class TextTemplateFormatter { return velocityContext; } - public static Template getTemplate(String name, String path) { + public Template getTemplate(String name, String path) { String templateFilePath; Template template; try { templateFilePath = Paths.get(path, name + ".vm").toString(); - template = Context.getVelocityEngine().getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); + template = velocityEngine.getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); } catch (ResourceNotFoundException error) { LOGGER.warn("Notification template error", error); templateFilePath = Paths.get(path, "unknown.vm").toString(); - template = Context.getVelocityEngine().getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); + template = velocityEngine.getTemplate(templateFilePath, StandardCharsets.UTF_8.name()); } return template; } - public static NotificationMessage formatMessage(VelocityContext velocityContext, String name, String templatePath) { + public NotificationMessage formatMessage(VelocityContext velocityContext, String name, String templatePath) { StringWriter writer = new StringWriter(); getTemplate(name, templatePath).merge(velocityContext, writer); return new NotificationMessage((String) velocityContext.get("subject"), writer.toString()); diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 3f1667568..5787b7ef2 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -23,7 +23,6 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.ws.rs.client.Client; @@ -31,7 +30,7 @@ import javax.ws.rs.client.Entity; public class NotificatorFirebase implements Notificator { - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; private final Client client; private final String url; @@ -54,14 +53,15 @@ public class NotificatorFirebase implements Notificator { } @Inject - public NotificatorFirebase(Config config, CacheManager cacheManager, Client client) { + public NotificatorFirebase(Config config, NotificationFormatter notificationFormatter, Client client) { this( - cacheManager, client, "https://fcm.googleapis.com/fcm/send", + notificationFormatter, client, "https://fcm.googleapis.com/fcm/send", config.getString(Keys.NOTIFICATOR_FIREBASE_KEY)); } - protected NotificatorFirebase(CacheManager cacheManager, Client client, String url, String key) { - this.cacheManager = cacheManager; + protected NotificatorFirebase( + NotificationFormatter notificationFormatter, Client client, String url, String key) { + this.notificationFormatter = notificationFormatter; this.client = client; this.url = url; this.key = key; @@ -71,7 +71,7 @@ public class NotificatorFirebase implements Notificator { public void send(User user, Event event, Position position) { if (user.getAttributes().containsKey("notificationTokens")) { - var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); + var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); Notification notification = new Notification(); notification.title = shortMessage.getSubject(); diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index fe8d69af2..647832166 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -20,10 +20,8 @@ import org.traccar.database.MailManager; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -import org.traccar.notification.NotificationMessage; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; -import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.mail.MessagingException; @@ -31,19 +29,18 @@ import javax.mail.MessagingException; public class NotificatorMail implements Notificator { private final MailManager mailManager; - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; @Inject - public NotificatorMail(MailManager mailManager, CacheManager cacheManager) { + public NotificatorMail(MailManager mailManager, NotificationFormatter notificationFormatter) { this.mailManager = mailManager; - this.cacheManager = cacheManager; + this.notificationFormatter = notificationFormatter; } @Override public void send(User user, Event event, Position position) throws MessageException { try { - NotificationMessage fullMessage = NotificationFormatter.formatMessage( - cacheManager, user, event, position, "full"); + var fullMessage = notificationFormatter.formatMessage(user, event, position, "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } catch (MessagingException e) { throw new MessageException(e); diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 2ac489dd6..32ceae780 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -22,7 +22,6 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.ws.rs.client.Client; @@ -30,7 +29,7 @@ import javax.ws.rs.client.Entity; public class NotificatorPushover implements Notificator { - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; private final Client client; private final String url; @@ -51,8 +50,8 @@ public class NotificatorPushover implements Notificator { } @Inject - public NotificatorPushover(Config config, CacheManager cacheManager, Client client) { - this.cacheManager = cacheManager; + public NotificatorPushover(Config config, NotificationFormatter notificationFormatter, Client client) { + this.notificationFormatter = notificationFormatter; this.client = client; url = "https://api.pushover.net/1/messages.json"; token = config.getString(Keys.NOTIFICATOR_PUSHOVER_TOKEN); @@ -70,7 +69,7 @@ public class NotificatorPushover implements Notificator { device = user.getString("notificator.pushover.device").replaceAll(" *, *", ","); } - var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); + var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); Message message = new Message(); message.token = token; diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index f4d1de0cb..544b67a5e 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -22,8 +22,6 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; -import org.traccar.notification.NotificationMessage; -import org.traccar.session.cache.CacheManager; import org.traccar.sms.SmsManager; import javax.inject.Inject; @@ -31,21 +29,21 @@ import javax.inject.Inject; public class NotificatorSms implements Notificator { private final SmsManager smsManager; - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; private final StatisticsManager statisticsManager; @Inject - public NotificatorSms(SmsManager smsManager, CacheManager cacheManager, StatisticsManager statisticsManager) { + public NotificatorSms( + SmsManager smsManager, NotificationFormatter notificationFormatter, StatisticsManager statisticsManager) { this.smsManager = smsManager; - this.cacheManager = cacheManager; + this.notificationFormatter = notificationFormatter; this.statisticsManager = statisticsManager; } @Override public void send(User user, Event event, Position position) throws MessageException, InterruptedException { if (user.getPhone() != null) { - NotificationMessage shortMessage = NotificationFormatter.formatMessage( - cacheManager, user, event, position, "short"); + var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); statisticsManager.registerSms(); smsManager.sendMessage(user.getPhone(), shortMessage.getBody(), false); } diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index 1dccf2c04..a00cd36f1 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -23,7 +23,6 @@ import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; -import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.ws.rs.client.Client; @@ -31,7 +30,7 @@ import javax.ws.rs.client.Entity; public class NotificatorTelegram implements Notificator { - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; private final Client client; private final String urlSendText; @@ -62,8 +61,8 @@ public class NotificatorTelegram implements Notificator { } @Inject - public NotificatorTelegram(Config config, CacheManager cacheManager, Client client) { - this.cacheManager = cacheManager; + public NotificatorTelegram(Config config, NotificationFormatter notificationFormatter, Client client) { + this.notificationFormatter = notificationFormatter; this.client = client; urlSendText = String.format( "https://api.telegram.org/bot%s/sendMessage", config.getString(Keys.NOTIFICATOR_TELEGRAM_KEY)); @@ -85,7 +84,7 @@ public class NotificatorTelegram implements Notificator { @Override public void send(User user, Event event, Position position) { - var shortMessage = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); + var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); TextMessage message = new TextMessage(); message.chatId = user.getString("telegramChatId"); diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 0827567ae..8f1260e96 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -17,7 +17,7 @@ package org.traccar.notificators; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.session.cache.CacheManager; +import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; import javax.ws.rs.client.Client; @@ -25,9 +25,9 @@ import javax.ws.rs.client.Client; public class NotificatorTraccar extends NotificatorFirebase { @Inject - public NotificatorTraccar(Config config, CacheManager cacheManager, Client client) { + public NotificatorTraccar(Config config, NotificationFormatter notificationFormatter, Client client) { super( - cacheManager, client, "https://www.traccar.org/push/", + notificationFormatter, client, "https://www.traccar.org/push/", config.getString(Keys.NOTIFICATOR_TRACCAR_KEY)); } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 402f7a9f0..3d899584d 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -21,19 +21,18 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import org.traccar.session.ConnectionManager; -import org.traccar.session.cache.CacheManager; import javax.inject.Inject; public final class NotificatorWeb implements Notificator { private final ConnectionManager connectionManager; - private final CacheManager cacheManager; + private final NotificationFormatter notificationFormatter; @Inject - public NotificatorWeb(ConnectionManager connectionManager, CacheManager cacheManager) { + public NotificatorWeb(ConnectionManager connectionManager, NotificationFormatter notificationFormatter) { this.connectionManager = connectionManager; - this.cacheManager = cacheManager; + this.notificationFormatter = notificationFormatter; } @Override @@ -49,7 +48,7 @@ public final class NotificatorWeb implements Notificator { copy.setMaintenanceId(event.getMaintenanceId()); copy.getAttributes().putAll(event.getAttributes()); - var message = NotificationFormatter.formatMessage(cacheManager, user, event, position, "short"); + var message = notificationFormatter.formatMessage(user, event, position, "short"); copy.set("message", message.getBody()); connectionManager.updateEvent(user.getId(), copy); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 706475241..95c43f8a0 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -16,6 +16,7 @@ */ package org.traccar.reports.common; +import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.tools.generic.DateTool; import org.apache.velocity.tools.generic.NumberTool; import org.jxls.area.Area; @@ -74,18 +75,21 @@ public class ReportUtils { private final IdentityManager identityManager; private final DeviceManager deviceManager; private final TripsConfig tripsConfig; + private final VelocityEngine velocityEngine; private final Geocoder geocoder; @Inject public ReportUtils( Config config, Storage storage, PermissionsService permissionsService, IdentityManager identityManager, - DeviceManager deviceManager, TripsConfig tripsConfig, @Nullable Geocoder geocoder) { + DeviceManager deviceManager, TripsConfig tripsConfig, VelocityEngine velocityEngine, + @Nullable Geocoder geocoder) { this.config = config; this.storage = storage; this.permissionsService = permissionsService; this.identityManager = identityManager; this.deviceManager = deviceManager; this.tripsConfig = tripsConfig; + this.velocityEngine = velocityEngine; this.geocoder = geocoder; } @@ -153,7 +157,7 @@ public class ReportUtils { context.putVar("distanceUnit", UserUtil.getDistanceUnit(server, user)); context.putVar("speedUnit", UserUtil.getSpeedUnit(server, user)); context.putVar("volumeUnit", UserUtil.getVolumeUnit(server, user)); - context.putVar("webUrl", Context.getVelocityEngine().getProperty("web.url")); + context.putVar("webUrl", velocityEngine.getProperty("web.url")); context.putVar("dateTool", new DateTool()); context.putVar("numberTool", new NumberTool()); context.putVar("timezone", UserUtil.getTimezone(server, user)); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 92bfdae1c..1440c4c30 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -1,5 +1,6 @@ package org.traccar.reports; +import org.apache.velocity.app.VelocityEngine; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.api.security.PermissionsService; @@ -76,8 +77,8 @@ public class ReportUtilsTest extends BaseTest { @Test public void testCalculateSpentFuel() { ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), mock(TripsConfig.class), null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), mock(TripsConfig.class), mock(VelocityEngine.class), null); Position startPosition = new Position(); Position endPosition = new Position(); assertEquals(reportUtils.calculateFuel(startPosition, endPosition), 0.0, 0.01); @@ -101,8 +102,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -156,8 +157,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -227,8 +228,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -278,8 +279,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -307,8 +308,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -336,8 +337,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -365,8 +366,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -390,8 +391,8 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), - mockIdentityManager(), mock(DeviceManager.class), tripsConfig, null); + mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); -- cgit v1.2.3 From aa00ed23f96f91cfc879f02e61333511e3b7b11b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 14:11:01 -0700 Subject: Remove JSR353 support --- build.gradle | 1 - src/main/java/org/traccar/Context.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/build.gradle b/build.gradle index 8c196043a..46227d1ff 100644 --- a/build.gradle +++ b/build.gradle @@ -63,7 +63,6 @@ dependencies { implementation "org.glassfish.jersey.inject:jersey-hk2:$jerseyVersion" implementation "org.glassfish.hk2:guice-bridge:2.6.1" // same version as jersey-hk2 implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" - implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" implementation "org.liquibase:liquibase-core:4.7.0" implementation "com.sun.mail:javax.mail:1.6.2" implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 627acd4e2..68a711878 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -17,7 +17,6 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr353.JSR353Module; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; @@ -140,7 +139,6 @@ public final class Context { if (config.getBoolean(Keys.WEB_SANITIZE)) { objectMapper.registerModule(new SanitizerModule()); } - objectMapper.registerModule(new JSR353Module()); objectMapper.setConfig( objectMapper.getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); -- cgit v1.2.3 From 4025a42c42e34bb620f4263de05781a10ddc7a9d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 14:27:01 -0700 Subject: Inject object mapper --- src/main/java/org/traccar/Context.java | 17 +---------------- src/main/java/org/traccar/MainModule.java | 17 +++++++++++++---- src/main/java/org/traccar/api/AsyncSocket.java | 9 ++++++--- .../java/org/traccar/api/AsyncSocketServlet.java | 13 +++++++++++-- .../java/org/traccar/api/ObjectMapperProvider.java | 4 ++-- .../java/org/traccar/database/DataManager.java | 3 ++- .../java/org/traccar/storage/DatabaseStorage.java | 19 +++++++++++-------- .../java/org/traccar/storage/QueryBuilder.java | 22 +++++++++++++++------- src/main/java/org/traccar/web/WebServer.java | 7 +++++-- 9 files changed, 66 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 68a711878..54bb2af4b 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -16,7 +16,6 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; @@ -29,7 +28,6 @@ import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; -import org.traccar.helper.SanitizerModule; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; @@ -55,12 +53,6 @@ public final class Context { return config; } - private static ObjectMapper objectMapper; - - public static ObjectMapper getObjectMapper() { - return objectMapper; - } - private static IdentityManager identityManager; public static IdentityManager getIdentityManager() { @@ -119,7 +111,7 @@ public final class Context { @Override public ObjectMapper getContext(Class clazz) { - return objectMapper; + return Main.getInjector().getInstance(ObjectMapper.class); } } @@ -135,13 +127,6 @@ public final class Context { throw e; } - objectMapper = new ObjectMapper(); - if (config.getBoolean(Keys.WEB_SANITIZE)) { - objectMapper.registerModule(new SanitizerModule()); - } - objectMapper.setConfig( - objectMapper.getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); - client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); if (config.hasKey(Keys.DATABASE_URL)) { diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a6f983a6b..794735daf 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -16,7 +16,9 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import com.google.inject.AbstractModule; +import com.google.inject.Injector; import com.google.inject.Provides; import com.google.inject.Scopes; import io.netty.util.HashedWheelTimer; @@ -28,6 +30,7 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; +import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; @@ -85,8 +88,14 @@ public class MainModule extends AbstractModule { } @Provides - public static ObjectMapper provideObjectMapper() { - return Context.getObjectMapper(); + public static ObjectMapper provideObjectMapper(Config config) { + ObjectMapper objectMapper = new ObjectMapper(); + if (config.getBoolean(Keys.WEB_SANITIZE)) { + objectMapper.registerModule(new SanitizerModule()); + } + objectMapper.setConfig(objectMapper + .getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); + return objectMapper; } @Provides @@ -145,9 +154,9 @@ public class MainModule extends AbstractModule { } @Provides - public static WebServer provideWebServer(Config config) { + public static WebServer provideWebServer(Injector injector, Config config) { if (config.hasKey(Keys.WEB_PORT)) { - return new WebServer(config); + return new WebServer(injector, config); } return null; } diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java index b5902c4fb..2b866176b 100644 --- a/src/main/java/org/traccar/api/AsyncSocket.java +++ b/src/main/java/org/traccar/api/AsyncSocket.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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.api; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.slf4j.Logger; @@ -39,9 +40,11 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U private static final String KEY_POSITIONS = "positions"; private static final String KEY_EVENTS = "events"; + private final ObjectMapper objectMapper; private final long userId; - public AsyncSocket(long userId) { + public AsyncSocket(ObjectMapper objectMapper, long userId) { + this.objectMapper = objectMapper; this.userId = userId; } @@ -92,7 +95,7 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U private void sendData(Map> data) { if (isConnected()) { try { - getRemote().sendString(Context.getObjectMapper().writeValueAsString(data), null); + getRemote().sendString(objectMapper.writeValueAsString(data), null); } catch (JsonProcessingException e) { LOGGER.warn("Socket JSON formatting error", e); } diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index a964ead10..4e55dfebf 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,24 +15,33 @@ */ package org.traccar.api; +import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.traccar.Context; import org.traccar.api.resource.SessionResource; import org.traccar.config.Keys; +import javax.inject.Inject; import javax.servlet.http.HttpSession; import java.time.Duration; public class AsyncSocketServlet extends JettyWebSocketServlet { + private final ObjectMapper objectMapper; + + @Inject + public AsyncSocketServlet(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + @Override public void configure(JettyWebSocketServletFactory factory) { factory.setIdleTimeout(Duration.ofMillis(Context.getConfig().getLong(Keys.WEB_TIMEOUT))); factory.setCreator((req, resp) -> { if (req.getSession() != null) { long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); - return new AsyncSocket(userId); + return new AsyncSocket(objectMapper, userId); } else { return null; } diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java index f81b20917..cb7adab6c 100644 --- a/src/main/java/org/traccar/api/ObjectMapperProvider.java +++ b/src/main/java/org/traccar/api/ObjectMapperProvider.java @@ -16,7 +16,7 @@ package org.traccar.api; import com.fasterxml.jackson.databind.ObjectMapper; -import org.traccar.Context; +import org.traccar.Main; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; @@ -26,7 +26,7 @@ public class ObjectMapperProvider implements ContextResolver { @Override public ObjectMapper getContext(Class type) { - return Context.getObjectMapper(); + return Main.getInjector().getInstance(ObjectMapper.class); } } diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 29d70ec32..556f1e348 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -15,6 +15,7 @@ */ package org.traccar.database; +import com.fasterxml.jackson.databind.ObjectMapper; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import liquibase.Contexts; @@ -78,7 +79,7 @@ public class DataManager { initDatabase(); initDatabaseSchema(); - storage = new DatabaseStorage(dataSource); + storage = new DatabaseStorage(dataSource, Main.getInjector().getInstance(ObjectMapper.class)); } private void initDatabase() throws Exception { diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index fc468182e..661e792d4 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -15,6 +15,7 @@ */ package org.traccar.storage; +import com.fasterxml.jackson.databind.ObjectMapper; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; @@ -38,9 +39,11 @@ import java.util.stream.Collectors; public class DatabaseStorage extends Storage { private final DataSource dataSource; + private final ObjectMapper objectMapper; - public DatabaseStorage(DataSource dataSource) { + public DatabaseStorage(DataSource dataSource, ObjectMapper objectMapper) { this.dataSource = dataSource; + this.objectMapper = objectMapper; } @Override @@ -52,7 +55,7 @@ public class DatabaseStorage extends Storage { query.append(formatOrder(request.getOrder())); query.append(formatLimit(request.getLimit())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -72,7 +75,7 @@ public class DatabaseStorage extends Storage { query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> ':' + c)); query.append(")"); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); builder.setObject(entity); return builder.executeUpdate(); } catch (SQLException e) { @@ -88,7 +91,7 @@ public class DatabaseStorage extends Storage { query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c + " = :" + c)); query.append(formatCondition(request.getCondition())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); builder.setObject(entity); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); @@ -105,7 +108,7 @@ public class DatabaseStorage extends Storage { query.append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -133,7 +136,7 @@ public class DatabaseStorage extends Storage { Condition combinedCondition = Condition.merge(conditions); query.append(formatCondition(combinedCondition)); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString()); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(combinedCondition).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -151,7 +154,7 @@ public class DatabaseStorage extends Storage { query.append(permission.get().keySet().stream().map(key -> ':' + key).collect(Collectors.joining(", "))); query.append(")"); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); for (var entry : permission.get().entrySet()) { builder.setLong(entry.getKey(), entry.getValue()); } @@ -169,7 +172,7 @@ public class DatabaseStorage extends Storage { query.append(permission .get().keySet().stream().map(key -> key + " = :" + key).collect(Collectors.joining(" AND "))); try { - QueryBuilder builder = QueryBuilder.create(dataSource, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); for (var entry : permission.get().entrySet()) { builder.setLong(entry.getKey(), entry.getValue()); } diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index 874a046b4..8502d5f0b 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -16,6 +16,7 @@ package org.traccar.storage; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; @@ -45,13 +46,18 @@ public final class QueryBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(QueryBuilder.class); + private final ObjectMapper objectMapper; + private final Map> indexMap = new HashMap<>(); private Connection connection; private PreparedStatement statement; private final String query; private final boolean returnGeneratedKeys; - private QueryBuilder(DataSource dataSource, String query, boolean returnGeneratedKeys) throws SQLException { + private QueryBuilder( + DataSource dataSource, ObjectMapper objectMapper, + String query, boolean returnGeneratedKeys) throws SQLException { + this.objectMapper = objectMapper; this.query = query; this.returnGeneratedKeys = returnGeneratedKeys; if (query != null) { @@ -126,13 +132,15 @@ public final class QueryBuilder { return parsedQuery.toString(); } - public static QueryBuilder create(DataSource dataSource, String query) throws SQLException { - return new QueryBuilder(dataSource, query, false); + public static QueryBuilder create( + DataSource dataSource, ObjectMapper objectMapper, String query) throws SQLException { + return new QueryBuilder(dataSource, objectMapper, query, false); } public static QueryBuilder create( - DataSource dataSource, String query, boolean returnGeneratedKeys) throws SQLException { - return new QueryBuilder(dataSource, query, returnGeneratedKeys); + DataSource dataSource, ObjectMapper objectMapper, String query, + boolean returnGeneratedKeys) throws SQLException { + return new QueryBuilder(dataSource, objectMapper, query, returnGeneratedKeys); } private List indexes(String name) { @@ -295,7 +303,7 @@ public final class QueryBuilder { } else if (method.getReturnType().equals(byte[].class)) { setBlob(name, (byte[]) method.invoke(object)); } else { - setString(name, Context.getObjectMapper().writeValueAsString(method.invoke(object))); + setString(name, objectMapper.writeValueAsString(method.invoke(object))); } } catch (IllegalAccessException | InvocationTargetException | JsonProcessingException error) { LOGGER.warn("Get property error", error); @@ -378,7 +386,7 @@ public final class QueryBuilder { String value = resultSet.getString(name); if (value != null && !value.isEmpty()) { try { - method.invoke(object, Context.getObjectMapper().readValue(value, parameterType)); + method.invoke(object, objectMapper.readValue(value, parameterType)); } catch (InvocationTargetException | IllegalAccessException | IOException error) { LOGGER.warn("Set property error", error); } diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index fdbfc1464..933e8c845 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -15,6 +15,7 @@ */ package org.traccar.web; +import com.google.inject.Injector; import com.google.inject.servlet.GuiceFilter; import org.eclipse.jetty.http.HttpCookie; import org.eclipse.jetty.http.HttpMethod; @@ -78,10 +79,12 @@ public class WebServer implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); + private final Injector injector; private final Server server; @Inject - public WebServer(Config config) { + public WebServer(Injector injector, Config config) { + this.injector = injector; String address = config.getString(Keys.WEB_ADDRESS); int port = config.getInteger(Keys.WEB_PORT); if (address == null) { @@ -169,7 +172,7 @@ public class WebServer implements LifecycleObject { private void initApi(Config config, ServletContextHandler servletHandler) { servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); - servletHandler.addServlet(new ServletHolder(new AsyncSocketServlet()), "/api/socket"); + servletHandler.addServlet(new ServletHolder(injector.getInstance(AsyncSocketServlet.class)), "/api/socket"); JettyWebSocketServletContainerInitializer.configure(servletHandler, null); String mediaPath = config.getString(Keys.MEDIA_PATH); -- cgit v1.2.3 From 7c08991f12b4958135fdffc26f272677c03630ad Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 15:04:51 -0700 Subject: Inject network client --- src/main/java/org/traccar/Context.java | 22 ------- src/main/java/org/traccar/MainModule.java | 68 ++++++++++++---------- .../java/org/traccar/geocoder/BanGeocoder.java | 5 +- .../org/traccar/geocoder/BingMapsGeocoder.java | 5 +- .../java/org/traccar/geocoder/FactualGeocoder.java | 5 +- .../org/traccar/geocoder/GeoapifyGeocoder.java | 5 +- .../org/traccar/geocoder/GeocodeFarmGeocoder.java | 6 +- .../org/traccar/geocoder/GeocodeXyzGeocoder.java | 5 +- .../org/traccar/geocoder/GisgraphyGeocoder.java | 5 +- .../java/org/traccar/geocoder/GoogleGeocoder.java | 5 +- .../java/org/traccar/geocoder/HereGeocoder.java | 6 +- .../java/org/traccar/geocoder/JsonGeocoder.java | 9 +-- .../org/traccar/geocoder/MapQuestGeocoder.java | 5 +- .../org/traccar/geocoder/MapTilerGeocoder.java | 5 +- .../java/org/traccar/geocoder/MapboxGeocoder.java | 5 +- .../org/traccar/geocoder/MapmyIndiaGeocoder.java | 5 +- .../org/traccar/geocoder/NominatimGeocoder.java | 6 +- .../org/traccar/geocoder/OpenCageGeocoder.java | 6 +- .../traccar/geocoder/PositionStackGeocoder.java | 5 +- .../java/org/traccar/geocoder/TomTomGeocoder.java | 5 +- .../geolocation/GoogleGeolocationProvider.java | 8 ++- .../geolocation/MozillaGeolocationProvider.java | 8 ++- .../geolocation/OpenCellIdGeolocationProvider.java | 12 ++-- .../geolocation/UniversalGeolocationProvider.java | 12 ++-- .../geolocation/UnwiredGeolocationProvider.java | 16 ++--- .../org/traccar/notification/EventForwarder.java | 16 +++-- .../java/org/traccar/schedule/ScheduleManager.java | 15 +++-- .../java/org/traccar/schedule/ScheduleTask.java | 22 +++++++ .../schedule/TaskDeviceInactivityCheck.java | 22 +++++-- .../java/org/traccar/schedule/TaskHealthCheck.java | 23 +++++--- .../traccar/schedule/TaskWebSocketKeepalive.java | 17 ++++-- src/main/java/org/traccar/sms/HttpSmsClient.java | 23 ++++---- src/main/java/org/traccar/sms/SnsSmsClient.java | 24 +++----- .../speedlimit/OverpassSpeedLimitProvider.java | 10 ++-- .../java/org/traccar/geocoder/GeocoderTest.java | 30 +++++----- .../geolocation/GeolocationProviderTest.java | 11 +++- .../speedlimit/OverpassSpeedLimitProviderTest.java | 11 +++- 37 files changed, 279 insertions(+), 189 deletions(-) create mode 100644 src/main/java/org/traccar/schedule/ScheduleTask.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 54bb2af4b..62ad01c24 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -15,7 +15,6 @@ */ package org.traccar; -import com.fasterxml.jackson.databind.ObjectMapper; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; @@ -38,10 +37,6 @@ import org.traccar.notification.NotificatorManager; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.ext.ContextResolver; - public final class Context { private Context() { @@ -101,21 +96,6 @@ public final class Context { return notificationManager; } - private static Client client = ClientBuilder.newClient(); - - public static Client getClient() { - return client; - } - - private static class ObjectMapperContextResolver implements ContextResolver { - - @Override - public ObjectMapper getContext(Class clazz) { - return Main.getInjector().getInstance(ObjectMapper.class); - } - - } - public static void init(String configFile) throws Exception { try { @@ -127,8 +107,6 @@ public final class Context { throw e; } - client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); - if (config.hasKey(Keys.DATABASE_URL)) { dataManager = new DataManager(config); } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 794735daf..2c88dbc13 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,6 +30,7 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; +import org.traccar.database.UsersManager; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; import org.traccar.session.ConnectionManager; @@ -64,6 +65,7 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; @@ -75,6 +77,8 @@ import org.traccar.web.WebServer; import javax.annotation.Nullable; import javax.inject.Singleton; import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.ext.ContextResolver; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; @@ -125,7 +129,8 @@ public class MainModule extends AbstractModule { @Provides public static Client provideClient() { - return Context.getClient(); + return ClientBuilder.newClient().register( + (ContextResolver) clazz -> Main.getInjector().getInstance(ObjectMapper.class)); } @Provides @@ -135,11 +140,11 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static SmsManager provideSmsManager(Config config) { + public static SmsManager provideSmsManager(Config config, Client client) { if (config.hasKey(Keys.SMS_HTTP_URL)) { - return new HttpSmsClient(); + return new HttpSmsClient(config, client); } else if (config.hasKey(Keys.SMS_AWS_REGION)) { - return new SnsSmsClient(); + return new SnsSmsClient(config); } return null; } @@ -163,7 +168,7 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static Geocoder provideGeocoder(Config config) { + public static Geocoder provideGeocoder(Config config, Client client) { if (config.getBoolean(Keys.GEOCODER_ENABLE)) { String type = config.getString(Keys.GEOCODER_TYPE, "google"); String url = config.getString(Keys.GEOCODER_URL); @@ -176,39 +181,39 @@ public class MainModule extends AbstractModule { int cacheSize = config.getInteger(Keys.GEOCODER_CACHE_SIZE); switch (type) { case "nominatim": - return new NominatimGeocoder(url, key, language, cacheSize, addressFormat); + return new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); case "gisgraphy": - return new GisgraphyGeocoder(url, cacheSize, addressFormat); + return new GisgraphyGeocoder(client, url, cacheSize, addressFormat); case "mapquest": - return new MapQuestGeocoder(url, key, cacheSize, addressFormat); + return new MapQuestGeocoder(client, url, key, cacheSize, addressFormat); case "opencage": - return new OpenCageGeocoder(url, key, language, cacheSize, addressFormat); + return new OpenCageGeocoder(client, url, key, language, cacheSize, addressFormat); case "bingmaps": - return new BingMapsGeocoder(url, key, cacheSize, addressFormat); + return new BingMapsGeocoder(client, url, key, cacheSize, addressFormat); case "factual": - return new FactualGeocoder(url, key, cacheSize, addressFormat); + return new FactualGeocoder(client, url, key, cacheSize, addressFormat); case "geocodefarm": - return new GeocodeFarmGeocoder(key, language, cacheSize, addressFormat); + return new GeocodeFarmGeocoder(client, key, language, cacheSize, addressFormat); case "geocodexyz": - return new GeocodeXyzGeocoder(key, cacheSize, addressFormat); + return new GeocodeXyzGeocoder(client, key, cacheSize, addressFormat); case "ban": - return new BanGeocoder(cacheSize, addressFormat); + return new BanGeocoder(client, cacheSize, addressFormat); case "here": - return new HereGeocoder(url, id, key, language, cacheSize, addressFormat); + return new HereGeocoder(client, url, id, key, language, cacheSize, addressFormat); case "mapmyindia": - return new MapmyIndiaGeocoder(url, key, cacheSize, addressFormat); + return new MapmyIndiaGeocoder(client, url, key, cacheSize, addressFormat); case "tomtom": - return new TomTomGeocoder(url, key, cacheSize, addressFormat); + return new TomTomGeocoder(client, url, key, cacheSize, addressFormat); case "positionstack": - return new PositionStackGeocoder(key, cacheSize, addressFormat); + return new PositionStackGeocoder(client, key, cacheSize, addressFormat); case "mapbox": - return new MapboxGeocoder(key, cacheSize, addressFormat); + return new MapboxGeocoder(client, key, cacheSize, addressFormat); case "maptiler": - return new MapTilerGeocoder(key, cacheSize, addressFormat); + return new MapTilerGeocoder(client, key, cacheSize, addressFormat); case "geoapify": - return new GeoapifyGeocoder(key, language, cacheSize, addressFormat); + return new GeoapifyGeocoder(client, key, language, cacheSize, addressFormat); default: - return new GoogleGeocoder(key, language, cacheSize, addressFormat); + return new GoogleGeocoder(client, key, language, cacheSize, addressFormat); } } return null; @@ -216,20 +221,20 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static GeolocationProvider provideGeolocationProvider(Config config) { + public static GeolocationProvider provideGeolocationProvider(Config config, Client client) { if (config.getBoolean(Keys.GEOLOCATION_ENABLE)) { String type = config.getString(Keys.GEOLOCATION_TYPE, "mozilla"); String url = config.getString(Keys.GEOLOCATION_URL); String key = config.getString(Keys.GEOLOCATION_KEY); switch (type) { case "google": - return new GoogleGeolocationProvider(key); + return new GoogleGeolocationProvider(client, key); case "opencellid": - return new OpenCellIdGeolocationProvider(url, key); + return new OpenCellIdGeolocationProvider(client, url, key); case "unwired": - return new UnwiredGeolocationProvider(url, key); + return new UnwiredGeolocationProvider(client, url, key); default: - return new MozillaGeolocationProvider(key); + return new MozillaGeolocationProvider(client, key); } } return null; @@ -237,14 +242,14 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static SpeedLimitProvider provideSpeedLimitProvider(Config config) { + public static SpeedLimitProvider provideSpeedLimitProvider(Config config, Client client) { if (config.getBoolean(Keys.SPEED_LIMIT_ENABLE)) { String type = config.getString(Keys.SPEED_LIMIT_TYPE, "overpass"); String url = config.getString(Keys.SPEED_LIMIT_URL); switch (type) { case "overpass": default: - return new OverpassSpeedLimitProvider(url); + return new OverpassSpeedLimitProvider(client, url); } } return null; @@ -286,9 +291,10 @@ public class MainModule extends AbstractModule { } @Provides - public static EventForwarder provideEventForwarder(Config config) { + public static EventForwarder provideEventForwarder( + Config config, Client client, CacheManager cacheManager, UsersManager usersManager) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - return new EventForwarder(config); + return new EventForwarder(config, client, cacheManager, usersManager); } return null; } diff --git a/src/main/java/org/traccar/geocoder/BanGeocoder.java b/src/main/java/org/traccar/geocoder/BanGeocoder.java index b1f0900a4..f878a8bab 100644 --- a/src/main/java/org/traccar/geocoder/BanGeocoder.java +++ b/src/main/java/org/traccar/geocoder/BanGeocoder.java @@ -22,11 +22,12 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class BanGeocoder extends JsonGeocoder { - public BanGeocoder(int cacheSize, AddressFormat addressFormat) { - super("https://api-adresse.data.gouv.fr/reverse/?lat=%f&lon=%f", cacheSize, addressFormat); + public BanGeocoder(Client client, int cacheSize, AddressFormat addressFormat) { + super(client, "https://api-adresse.data.gouv.fr/reverse/?lat=%f&lon=%f", cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java b/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java index 32a26ee0c..01e33c2ea 100644 --- a/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java +++ b/src/main/java/org/traccar/geocoder/BingMapsGeocoder.java @@ -18,11 +18,12 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class BingMapsGeocoder extends JsonGeocoder { - public BingMapsGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(url + "/Locations/%f,%f?key=" + key + "&include=ciso2", cacheSize, addressFormat); + public BingMapsGeocoder(Client client, String url, String key, int cacheSize, AddressFormat addressFormat) { + super(client, url + "/Locations/%f,%f?key=" + key + "&include=ciso2", cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/FactualGeocoder.java b/src/main/java/org/traccar/geocoder/FactualGeocoder.java index f540eb8fe..384f46b0e 100644 --- a/src/main/java/org/traccar/geocoder/FactualGeocoder.java +++ b/src/main/java/org/traccar/geocoder/FactualGeocoder.java @@ -17,6 +17,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class FactualGeocoder extends JsonGeocoder { @@ -28,8 +29,8 @@ public class FactualGeocoder extends JsonGeocoder { return url; } - public FactualGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key), cacheSize, addressFormat); + public FactualGeocoder(Client client, String url, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java b/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java index ef0e4c8bd..4748d6a2c 100644 --- a/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GeoapifyGeocoder.java @@ -17,6 +17,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class GeoapifyGeocoder extends JsonGeocoder { @@ -31,8 +32,8 @@ public class GeoapifyGeocoder extends JsonGeocoder { return url; } - public GeoapifyGeocoder(String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key, language), cacheSize, addressFormat); + public GeoapifyGeocoder(Client client, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java b/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java index 39a3300a0..2af95910f 100644 --- a/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GeocodeFarmGeocoder.java @@ -16,6 +16,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class GeocodeFarmGeocoder extends JsonGeocoder { @@ -30,8 +31,9 @@ public class GeocodeFarmGeocoder extends JsonGeocoder { } return url; } - public GeocodeFarmGeocoder(String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key, language), cacheSize, addressFormat); + public GeocodeFarmGeocoder( + Client client, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java b/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java index aca360c3d..96491ece3 100644 --- a/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GeocodeXyzGeocoder.java @@ -16,6 +16,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class GeocodeXyzGeocoder extends JsonGeocoder { @@ -27,8 +28,8 @@ public class GeocodeXyzGeocoder extends JsonGeocoder { return url; } - public GeocodeXyzGeocoder(String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key), cacheSize, addressFormat); + public GeocodeXyzGeocoder(Client client, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java b/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java index b4881a006..0589eb000 100644 --- a/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GisgraphyGeocoder.java @@ -16,6 +16,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class GisgraphyGeocoder extends JsonGeocoder { @@ -27,8 +28,8 @@ public class GisgraphyGeocoder extends JsonGeocoder { return url; } - public GisgraphyGeocoder(String url, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url), cacheSize, addressFormat); + public GisgraphyGeocoder(Client client, String url, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/GoogleGeocoder.java b/src/main/java/org/traccar/geocoder/GoogleGeocoder.java index 9494cab45..4d9ec8f36 100644 --- a/src/main/java/org/traccar/geocoder/GoogleGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GoogleGeocoder.java @@ -18,6 +18,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonString; +import javax.ws.rs.client.Client; public class GoogleGeocoder extends JsonGeocoder { @@ -32,8 +33,8 @@ public class GoogleGeocoder extends JsonGeocoder { return url; } - public GoogleGeocoder(String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key, language), cacheSize, addressFormat); + public GoogleGeocoder(Client client, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/HereGeocoder.java b/src/main/java/org/traccar/geocoder/HereGeocoder.java index 40390e65b..eb639995e 100644 --- a/src/main/java/org/traccar/geocoder/HereGeocoder.java +++ b/src/main/java/org/traccar/geocoder/HereGeocoder.java @@ -16,6 +16,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class HereGeocoder extends JsonGeocoder { @@ -35,8 +36,9 @@ public class HereGeocoder extends JsonGeocoder { } public HereGeocoder( - String url, String id, String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, id, key, language), cacheSize, addressFormat); + Client client, String url, String id, String key, String language, + int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, id, key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/JsonGeocoder.java b/src/main/java/org/traccar/geocoder/JsonGeocoder.java index f20aa79d6..0262de18c 100644 --- a/src/main/java/org/traccar/geocoder/JsonGeocoder.java +++ b/src/main/java/org/traccar/geocoder/JsonGeocoder.java @@ -17,13 +17,12 @@ package org.traccar.geocoder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.Main; import org.traccar.database.StatisticsManager; import javax.json.JsonObject; import javax.ws.rs.WebApplicationException; -import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.Client; import javax.ws.rs.client.InvocationCallback; import java.util.AbstractMap; import java.util.Collections; @@ -34,12 +33,14 @@ public abstract class JsonGeocoder implements Geocoder { private static final Logger LOGGER = LoggerFactory.getLogger(JsonGeocoder.class); + private final Client client; private final String url; private final AddressFormat addressFormat; private Map, String> cache; - public JsonGeocoder(String url, final int cacheSize, AddressFormat addressFormat) { + public JsonGeocoder(Client client, String url, final int cacheSize, AddressFormat addressFormat) { + this.client = client; this.url = url; this.addressFormat = addressFormat; if (cacheSize > 0) { @@ -101,7 +102,7 @@ public abstract class JsonGeocoder implements Geocoder { Main.getInjector().getInstance(StatisticsManager.class).registerGeocoderRequest(); } - Invocation.Builder request = Context.getClient().target(String.format(url, latitude, longitude)).request(); + var request = client.target(String.format(url, latitude, longitude)).request(); if (callback != null) { request.async().get(new InvocationCallback() { diff --git a/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java b/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java index 8dc3f76f0..3f2554c6e 100644 --- a/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapQuestGeocoder.java @@ -18,6 +18,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class MapQuestGeocoder extends JsonGeocoder { @@ -29,8 +30,8 @@ public class MapQuestGeocoder extends JsonGeocoder { return url; } - public MapQuestGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key), cacheSize, addressFormat); + public MapQuestGeocoder(Client client, String url, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java b/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java index 6b688a6e8..203f5f99b 100644 --- a/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java @@ -17,11 +17,12 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class MapTilerGeocoder extends JsonGeocoder { - public MapTilerGeocoder(String key, int cacheSize, AddressFormat addressFormat) { - super("https://api.maptiler.com/geocoding/%2$f,%1$f.json?key=" + key, cacheSize, addressFormat); + public MapTilerGeocoder(Client client, String key, int cacheSize, AddressFormat addressFormat) { + super(client, "https://api.maptiler.com/geocoding/%2$f,%1$f.json?key=" + key, cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/MapboxGeocoder.java b/src/main/java/org/traccar/geocoder/MapboxGeocoder.java index 9b987c9d8..72bfb53f5 100644 --- a/src/main/java/org/traccar/geocoder/MapboxGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapboxGeocoder.java @@ -18,6 +18,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; import javax.json.JsonString; +import javax.ws.rs.client.Client; public class MapboxGeocoder extends JsonGeocoder { @@ -25,8 +26,8 @@ public class MapboxGeocoder extends JsonGeocoder { return "https://api.mapbox.com/geocoding/v5/mapbox.places/%2$f,%1$f.json?access_token=" + key; } - public MapboxGeocoder(String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key), cacheSize, addressFormat); + public MapboxGeocoder(Client client, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java b/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java index 2b70708a1..dea295cca 100644 --- a/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapmyIndiaGeocoder.java @@ -17,11 +17,12 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class MapmyIndiaGeocoder extends JsonGeocoder { - public MapmyIndiaGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(url + "/" + key + "/rev_geocode?lat=%f&lng=%f", cacheSize, addressFormat); + public MapmyIndiaGeocoder(Client client, String url, String key, int cacheSize, AddressFormat addressFormat) { + super(client, url + "/" + key + "/rev_geocode?lat=%f&lng=%f", cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/NominatimGeocoder.java b/src/main/java/org/traccar/geocoder/NominatimGeocoder.java index 8db25bf15..b731549f7 100644 --- a/src/main/java/org/traccar/geocoder/NominatimGeocoder.java +++ b/src/main/java/org/traccar/geocoder/NominatimGeocoder.java @@ -16,6 +16,7 @@ package org.traccar.geocoder; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class NominatimGeocoder extends JsonGeocoder { @@ -33,8 +34,9 @@ public class NominatimGeocoder extends JsonGeocoder { return url; } - public NominatimGeocoder(String url, String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key, language), cacheSize, addressFormat); + public NominatimGeocoder( + Client client, String url, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java index bbcc00cd0..fb61440aa 100644 --- a/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java +++ b/src/main/java/org/traccar/geocoder/OpenCageGeocoder.java @@ -18,6 +18,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class OpenCageGeocoder extends JsonGeocoder { @@ -32,8 +33,9 @@ public class OpenCageGeocoder extends JsonGeocoder { return url; } - public OpenCageGeocoder(String url, String key, String language, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key, language), cacheSize, addressFormat); + public OpenCageGeocoder( + Client client, String url, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java b/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java index 2674a68ca..9778d9eda 100644 --- a/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java +++ b/src/main/java/org/traccar/geocoder/PositionStackGeocoder.java @@ -17,6 +17,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class PositionStackGeocoder extends JsonGeocoder { @@ -24,8 +25,8 @@ public class PositionStackGeocoder extends JsonGeocoder { return "http://api.positionstack.com/v1/reverse?access_key=" + key + "&query=%f,%f"; } - public PositionStackGeocoder(String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(key), cacheSize, addressFormat); + public PositionStackGeocoder(Client client, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/TomTomGeocoder.java b/src/main/java/org/traccar/geocoder/TomTomGeocoder.java index 232b24396..9bb36efc2 100644 --- a/src/main/java/org/traccar/geocoder/TomTomGeocoder.java +++ b/src/main/java/org/traccar/geocoder/TomTomGeocoder.java @@ -17,6 +17,7 @@ package org.traccar.geocoder; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.ws.rs.client.Client; public class TomTomGeocoder extends JsonGeocoder { @@ -28,8 +29,8 @@ public class TomTomGeocoder extends JsonGeocoder { return url; } - public TomTomGeocoder(String url, String key, int cacheSize, AddressFormat addressFormat) { - super(formatUrl(url, key), cacheSize, addressFormat); + public TomTomGeocoder(Client client, String url, String key, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java b/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java index 5901b47cd..8f0f3b704 100644 --- a/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/GoogleGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,14 @@ */ package org.traccar.geolocation; +import javax.ws.rs.client.Client; + public class GoogleGeolocationProvider extends UniversalGeolocationProvider { private static final String URL = "https://www.googleapis.com/geolocation/v1/geolocate"; - public GoogleGeolocationProvider(String key) { - super(URL, key); + public GoogleGeolocationProvider(Client client, String key) { + super(client, URL, key); } } diff --git a/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java b/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java index c6a73a52b..3b4ba4e1f 100644 --- a/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/MozillaGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,14 @@ */ package org.traccar.geolocation; +import javax.ws.rs.client.Client; + public class MozillaGeolocationProvider extends UniversalGeolocationProvider { private static final String URL = "https://location.services.mozilla.com/v1/geolocate"; - public MozillaGeolocationProvider(String key) { - super(URL, key != null ? key : "test"); + public MozillaGeolocationProvider(Client client, String key) { + super(client, URL, key != null ? key : "test"); } } diff --git a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java index 2535970d3..82fcf42ab 100644 --- a/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/OpenCellIdGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,18 +15,20 @@ */ package org.traccar.geolocation; -import org.traccar.Context; import org.traccar.model.CellTower; import org.traccar.model.Network; import javax.json.JsonObject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.InvocationCallback; public class OpenCellIdGeolocationProvider implements GeolocationProvider { - private String url; + private final Client client; + private final String url; - public OpenCellIdGeolocationProvider(String url, String key) { + public OpenCellIdGeolocationProvider(Client client, String url, String key) { + this.client = client; if (url == null) { url = "http://opencellid.org/cell/get"; } @@ -41,7 +43,7 @@ public class OpenCellIdGeolocationProvider implements GeolocationProvider { String request = String.format(url, cellTower.getMobileCountryCode(), cellTower.getMobileNetworkCode(), cellTower.getLocationAreaCode(), cellTower.getCellId()); - Context.getClient().target(request).request().async().get(new InvocationCallback() { + client.target(request).request().async().get(new InvocationCallback() { @Override public void completed(JsonObject json) { if (json.containsKey("lat") && json.containsKey("lon")) { diff --git a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java index 33cd84a47..7a3f71ee1 100644 --- a/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/UniversalGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,26 +15,26 @@ */ package org.traccar.geolocation; -import org.traccar.Context; import org.traccar.model.Network; import javax.json.JsonObject; -import javax.ws.rs.client.AsyncInvoker; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; public class UniversalGeolocationProvider implements GeolocationProvider { + private final Client client; private final String url; - public UniversalGeolocationProvider(String url, String key) { + public UniversalGeolocationProvider(Client client, String url, String key) { + this.client = client; this.url = url + "?key=" + key; } @Override public void getLocation(Network network, final LocationProviderCallback callback) { - AsyncInvoker invoker = Context.getClient().target(url).request().async(); - invoker.post(Entity.json(network), new InvocationCallback() { + client.target(url).request().async().post(Entity.json(network), new InvocationCallback() { @Override public void completed(JsonObject json) { if (json.containsKey("error")) { diff --git a/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java b/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java index 963bcb688..14893b6a3 100644 --- a/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java +++ b/src/main/java/org/traccar/geolocation/UnwiredGeolocationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@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,22 +19,23 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import org.traccar.Context; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.WifiAccessPoint; import javax.json.JsonObject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; import java.util.Collection; public class UnwiredGeolocationProvider implements GeolocationProvider { - private String url; - private String key; + private final Client client; + private final String url; + private final String key; - private ObjectMapper objectMapper; + private final ObjectMapper objectMapper; private abstract static class NetworkMixIn { @JsonProperty("mcc") @@ -73,7 +74,8 @@ public class UnwiredGeolocationProvider implements GeolocationProvider { abstract Integer getSignalStrength(); } - public UnwiredGeolocationProvider(String url, String key) { + public UnwiredGeolocationProvider(Client client, String url, String key) { + this.client = client; this.url = url; this.key = key; @@ -88,7 +90,7 @@ public class UnwiredGeolocationProvider implements GeolocationProvider { ObjectNode json = objectMapper.valueToTree(network); json.put("token", key); - Context.getClient().target(url).request().async().post(Entity.json(json), new InvocationCallback() { + client.target(url).request().async().post(Entity.json(json), new InvocationCallback() { @Override public void completed(JsonObject json) { if (json.getString("status").equals("error")) { diff --git a/src/main/java/org/traccar/notification/EventForwarder.java b/src/main/java/org/traccar/notification/EventForwarder.java index b0494d74d..5afff1b7b 100644 --- a/src/main/java/org/traccar/notification/EventForwarder.java +++ b/src/main/java/org/traccar/notification/EventForwarder.java @@ -17,10 +17,9 @@ package org.traccar.notification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.UsersManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -28,6 +27,7 @@ import org.traccar.model.Maintenance; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; import javax.ws.rs.client.InvocationCallback; @@ -42,12 +42,16 @@ public class EventForwarder { private final String url; private final String header; + private final Client client; private final CacheManager cacheManager; + private final UsersManager usersManager; - public EventForwarder(Config config) { + public EventForwarder(Config config, Client client, CacheManager cacheManager, UsersManager usersManager) { + this.client = client; + this.cacheManager = cacheManager; + this.usersManager = usersManager; url = config.getString(Keys.EVENT_FORWARD_URL); header = config.getString(Keys.EVENT_FORWARD_HEADERS); - cacheManager = Main.getInjector().getInstance(CacheManager.class); } private static final String KEY_POSITION = "position"; @@ -59,7 +63,7 @@ public class EventForwarder { public final void forwardEvent(Event event, Position position, Set users) { - Invocation.Builder requestBuilder = Context.getClient().target(url).request(); + Invocation.Builder requestBuilder = client.target(url).request(); if (header != null && !header.isEmpty()) { for (String line: header.split("\\r?\\n")) { @@ -105,7 +109,7 @@ public class EventForwarder { data.put(KEY_MAINTENANCE, maintenance); } } - data.put(KEY_USERS, Context.getUsersManager().getItems(users)); + data.put(KEY_USERS, usersManager.getItems(users)); return data; } diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index 154de603a..6412a186a 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -15,24 +15,31 @@ */ package org.traccar.schedule; +import com.google.inject.Injector; import org.traccar.LifecycleObject; +import javax.inject.Inject; import javax.inject.Singleton; +import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @Singleton public class ScheduleManager implements LifecycleObject { + private final Injector injector; private ScheduledExecutorService executor; + @Inject + public ScheduleManager(Injector injector) { + this.injector = injector; + } + @Override public void start() { executor = Executors.newSingleThreadScheduledExecutor(); - - new TaskDeviceInactivityCheck().schedule(executor); - new TaskWebSocketKeepalive().schedule(executor); - new TaskHealthCheck().schedule(executor); + List.of(TaskDeviceInactivityCheck.class, TaskWebSocketKeepalive.class, TaskHealthCheck.class) + .forEach(task -> injector.getInstance(task).schedule(executor)); } @Override diff --git a/src/main/java/org/traccar/schedule/ScheduleTask.java b/src/main/java/org/traccar/schedule/ScheduleTask.java new file mode 100644 index 000000000..1b537213b --- /dev/null +++ b/src/main/java/org/traccar/schedule/ScheduleTask.java @@ -0,0 +1,22 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.schedule; + +import java.util.concurrent.ScheduledExecutorService; + +public interface ScheduleTask extends Runnable { + void schedule(ScheduledExecutorService executor); +} diff --git a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java index 80641d7d4..f2ed3c3b3 100644 --- a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java +++ b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,17 +15,19 @@ */ package org.traccar.schedule; -import org.traccar.Context; +import org.traccar.database.DeviceManager; +import org.traccar.database.NotificationManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class TaskDeviceInactivityCheck implements Runnable { +public class TaskDeviceInactivityCheck implements ScheduleTask { public static final String ATTRIBUTE_DEVICE_INACTIVITY_START = "deviceInactivityStart"; public static final String ATTRIBUTE_DEVICE_INACTIVITY_PERIOD = "deviceInactivityPeriod"; @@ -33,6 +35,16 @@ public class TaskDeviceInactivityCheck implements Runnable { private static final long CHECK_PERIOD_MINUTES = 15; + private final DeviceManager deviceManager; + private final NotificationManager notificationManager; + + @Inject + public TaskDeviceInactivityCheck(DeviceManager deviceManager, NotificationManager notificationManager) { + this.deviceManager = deviceManager; + this.notificationManager = notificationManager; + } + + @Override public void schedule(ScheduledExecutorService executor) { executor.scheduleAtFixedRate(this, CHECK_PERIOD_MINUTES, CHECK_PERIOD_MINUTES, TimeUnit.MINUTES); } @@ -43,7 +55,7 @@ public class TaskDeviceInactivityCheck implements Runnable { long checkPeriod = TimeUnit.MINUTES.toMillis(CHECK_PERIOD_MINUTES); Map events = new HashMap<>(); - for (Device device : Context.getDeviceManager().getAllDevices()) { + for (Device device : deviceManager.getAllDevices()) { if (device.getLastUpdate() != null && checkDevice(device, currentTime, checkPeriod)) { Event event = new Event(Event.TYPE_DEVICE_INACTIVE, device.getId()); event.set(ATTRIBUTE_LAST_UPDATE, device.getLastUpdate().getTime()); @@ -51,7 +63,7 @@ public class TaskDeviceInactivityCheck implements Runnable { } } - Context.getNotificationManager().updateEvents(events); + notificationManager.updateEvents(events); } private boolean checkDevice(Device device, long currentTime, long checkPeriod) { diff --git a/src/main/java/org/traccar/schedule/TaskHealthCheck.java b/src/main/java/org/traccar/schedule/TaskHealthCheck.java index 087cd3e63..a8c9873ce 100644 --- a/src/main/java/org/traccar/schedule/TaskHealthCheck.java +++ b/src/main/java/org/traccar/schedule/TaskHealthCheck.java @@ -19,23 +19,31 @@ import com.sun.jna.Library; import com.sun.jna.Native; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; +import javax.inject.Inject; +import javax.ws.rs.client.Client; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class TaskHealthCheck implements Runnable { +public class TaskHealthCheck implements ScheduleTask { private static final Logger LOGGER = LoggerFactory.getLogger(TaskHealthCheck.class); + private final Config config; + private final Client client; + private SystemD systemD; private boolean enabled; private long period; - public TaskHealthCheck() { - if (!Context.getConfig().getBoolean(Keys.WEB_DISABLE_HEALTH_CHECK) + @Inject + public TaskHealthCheck(Config config, Client client) { + this.config = config; + this.client = client; + if (!config.getBoolean(Keys.WEB_DISABLE_HEALTH_CHECK) && System.getProperty("os.name").toLowerCase().startsWith("linux")) { try { systemD = Native.load("systemd", SystemD.class); @@ -54,11 +62,12 @@ public class TaskHealthCheck implements Runnable { } private String getUrl() { - String address = Context.getConfig().getString(Keys.WEB_ADDRESS, "localhost"); - int port = Context.getConfig().getInteger(Keys.WEB_PORT); + String address = config.getString(Keys.WEB_ADDRESS, "localhost"); + int port = config.getInteger(Keys.WEB_PORT); return "http://" + address + ":" + port + "/api/server"; } + @Override public void schedule(ScheduledExecutorService executor) { if (enabled) { executor.scheduleAtFixedRate(this, period, period, TimeUnit.MILLISECONDS); @@ -68,7 +77,7 @@ public class TaskHealthCheck implements Runnable { @Override public void run() { LOGGER.debug("Health check running"); - int status = Context.getClient().target(getUrl()).request().get().getStatus(); + int status = client.target(getUrl()).request().get().getStatus(); if (status == 200) { int result = systemD.sd_notify(0, "WATCHDOG=1"); if (result < 0) { diff --git a/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java b/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java index 953b0efea..e6c2e8b6d 100644 --- a/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java +++ b/src/main/java/org/traccar/schedule/TaskWebSocketKeepalive.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,22 +15,31 @@ */ package org.traccar.schedule; -import org.traccar.Context; +import org.traccar.session.ConnectionManager; +import javax.inject.Inject; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class TaskWebSocketKeepalive implements Runnable { +public class TaskWebSocketKeepalive implements ScheduleTask { private static final long PERIOD_SECONDS = 55; + private final ConnectionManager connectionManager; + + @Inject + public TaskWebSocketKeepalive(ConnectionManager connectionManager) { + this.connectionManager = connectionManager; + } + + @Override public void schedule(ScheduledExecutorService executor) { executor.scheduleAtFixedRate(this, PERIOD_SECONDS, PERIOD_SECONDS, TimeUnit.SECONDS); } @Override public void run() { - Context.getConnectionManager().sendKeepalive(); + connectionManager.sendKeepalive(); } } diff --git a/src/main/java/org/traccar/sms/HttpSmsClient.java b/src/main/java/org/traccar/sms/HttpSmsClient.java index 5c3cef747..51b161594 100644 --- a/src/main/java/org/traccar/sms/HttpSmsClient.java +++ b/src/main/java/org/traccar/sms/HttpSmsClient.java @@ -16,11 +16,12 @@ */ package org.traccar.sms; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.DataConverter; import org.traccar.notification.MessageException; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; import javax.ws.rs.core.MediaType; @@ -31,6 +32,7 @@ import java.nio.charset.StandardCharsets; public class HttpSmsClient implements SmsManager { + private final Client client; private final String url; private final String authorizationHeader; private final String authorization; @@ -38,14 +40,15 @@ public class HttpSmsClient implements SmsManager { private final boolean encode; private final MediaType mediaType; - public HttpSmsClient() { - url = Context.getConfig().getString(Keys.SMS_HTTP_URL); - authorizationHeader = Context.getConfig().getString(Keys.SMS_HTTP_AUTHORIZATION_HEADER); - if (Context.getConfig().hasKey(Keys.SMS_HTTP_AUTHORIZATION)) { - authorization = Context.getConfig().getString(Keys.SMS_HTTP_AUTHORIZATION); + public HttpSmsClient(Config config, Client client) { + this.client = client; + url = config.getString(Keys.SMS_HTTP_URL); + authorizationHeader = config.getString(Keys.SMS_HTTP_AUTHORIZATION_HEADER); + if (config.hasKey(Keys.SMS_HTTP_AUTHORIZATION)) { + authorization = config.getString(Keys.SMS_HTTP_AUTHORIZATION); } else { - String user = Context.getConfig().getString(Keys.SMS_HTTP_USER); - String password = Context.getConfig().getString(Keys.SMS_HTTP_PASSWORD); + String user = config.getString(Keys.SMS_HTTP_USER); + String password = config.getString(Keys.SMS_HTTP_PASSWORD); if (user != null && password != null) { authorization = "Basic " + DataConverter.printBase64((user + ":" + password).getBytes(StandardCharsets.UTF_8)); @@ -53,7 +56,7 @@ public class HttpSmsClient implements SmsManager { authorization = null; } } - template = Context.getConfig().getString(Keys.SMS_HTTP_TEMPLATE).trim(); + template = config.getString(Keys.SMS_HTTP_TEMPLATE).trim(); if (template.charAt(0) == '{' || template.charAt(0) == '[') { encode = false; mediaType = MediaType.APPLICATION_JSON_TYPE; @@ -78,7 +81,7 @@ public class HttpSmsClient implements SmsManager { } private Invocation.Builder getRequestBuilder() { - Invocation.Builder builder = Context.getClient().target(url).request(); + Invocation.Builder builder = client.target(url).request(); if (authorization != null) { builder = builder.header(authorizationHeader, authorization); } diff --git a/src/main/java/org/traccar/sms/SnsSmsClient.java b/src/main/java/org/traccar/sms/SnsSmsClient.java index 49889ac89..ed5a325cc 100644 --- a/src/main/java/org/traccar/sms/SnsSmsClient.java +++ b/src/main/java/org/traccar/sms/SnsSmsClient.java @@ -27,7 +27,7 @@ import com.amazonaws.services.sns.model.PublishRequest; import com.amazonaws.services.sns.model.PublishResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import java.util.HashMap; @@ -38,19 +38,12 @@ public class SnsSmsClient implements SmsManager { private final AmazonSNSAsync snsClient; - public SnsSmsClient() { - if (Context.getConfig().hasKey(Keys.SMS_AWS_REGION) - && Context.getConfig().hasKey(Keys.SMS_AWS_ACCESS) - && Context.getConfig().hasKey(Keys.SMS_AWS_SECRET)) { - BasicAWSCredentials awsCredentials = - new BasicAWSCredentials(Context.getConfig().getString(Keys.SMS_AWS_ACCESS), - Context.getConfig().getString(Keys.SMS_AWS_SECRET)); - snsClient = AmazonSNSAsyncClientBuilder.standard() - .withRegion(Context.getConfig().getString(Keys.SMS_AWS_REGION)) - .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)).build(); - } else { - throw new RuntimeException("SNS Not Configured Properly. Please provide valid config."); - } + public SnsSmsClient(Config config) { + BasicAWSCredentials awsCredentials = new BasicAWSCredentials( + config.getString(Keys.SMS_AWS_ACCESS), config.getString(Keys.SMS_AWS_SECRET)); + snsClient = AmazonSNSAsyncClientBuilder.standard() + .withRegion(config.getString(Keys.SMS_AWS_REGION)) + .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)).build(); } @Override @@ -64,11 +57,12 @@ public class SnsSmsClient implements SmsManager { PublishRequest publishRequest = new PublishRequest().withMessage(message) .withPhoneNumber(destAddress).withMessageAttributes(smsAttributes); - snsClient.publishAsync(publishRequest, new AsyncHandler() { + snsClient.publishAsync(publishRequest, new AsyncHandler<>() { @Override public void onError(Exception exception) { LOGGER.error("SMS send failed", exception); } + @Override public void onSuccess(PublishRequest request, PublishResult result) { } diff --git a/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java b/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java index 429a47c76..edf089f37 100644 --- a/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java +++ b/src/main/java/org/traccar/speedlimit/OverpassSpeedLimitProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,19 +15,21 @@ */ package org.traccar.speedlimit; -import org.traccar.Context; import org.traccar.helper.UnitsConverter; import javax.json.JsonArray; import javax.json.JsonObject; import javax.ws.rs.client.AsyncInvoker; +import javax.ws.rs.client.Client; import javax.ws.rs.client.InvocationCallback; public class OverpassSpeedLimitProvider implements SpeedLimitProvider { + private final Client client; private final String url; - public OverpassSpeedLimitProvider(String url) { + public OverpassSpeedLimitProvider(Client client, String url) { + this.client = client; this.url = url + "?data=[out:json];way[maxspeed](around:100.0,%f,%f);out%%20tags;"; } @@ -46,7 +48,7 @@ public class OverpassSpeedLimitProvider implements SpeedLimitProvider { @Override public void getSpeedLimit(double latitude, double longitude, SpeedLimitProviderCallback callback) { String formattedUrl = String.format(url, latitude, longitude); - AsyncInvoker invoker = Context.getClient().target(formattedUrl).request().async(); + AsyncInvoker invoker = client.target(formattedUrl).request().async(); invoker.get(new InvocationCallback() { @Override public void completed(JsonObject json) { diff --git a/src/test/java/org/traccar/geocoder/GeocoderTest.java b/src/test/java/org/traccar/geocoder/GeocoderTest.java index 6a85777b1..ff33b1f1c 100644 --- a/src/test/java/org/traccar/geocoder/GeocoderTest.java +++ b/src/test/java/org/traccar/geocoder/GeocoderTest.java @@ -3,6 +3,8 @@ package org.traccar.geocoder; import org.junit.Ignore; import org.junit.Test; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; import java.util.Locale; import static org.junit.Assert.assertEquals; @@ -13,10 +15,12 @@ public class GeocoderTest { Locale.setDefault(Locale.US); } + private final Client client = ClientBuilder.newClient(); + @Ignore @Test public void testGoogle() { - Geocoder geocoder = new GoogleGeocoder(null, null, 0, new AddressFormat()); + Geocoder geocoder = new GoogleGeocoder(client, null, null, 0, new AddressFormat()); String address = geocoder.getAddress(31.776797, 35.211489, null); assertEquals("1 Ibn Shaprut St, Jerusalem, Jerusalem District, IL", address); } @@ -24,7 +28,7 @@ public class GeocoderTest { @Ignore @Test public void testNominatim() { - Geocoder geocoder = new NominatimGeocoder(null, null, null, 0, new AddressFormat()); + Geocoder geocoder = new NominatimGeocoder(client, null, null, null, 0, new AddressFormat()); String address = geocoder.getAddress(40.7337807, -73.9974401, null); assertEquals("35 West 9th Street, NYC, New York, US", address); } @@ -32,7 +36,7 @@ public class GeocoderTest { @Ignore @Test public void testGisgraphy() { - Geocoder geocoder = new GisgraphyGeocoder(null, 0, new AddressFormat()); + Geocoder geocoder = new GisgraphyGeocoder(client, null, 0, new AddressFormat()); String address = geocoder.getAddress(48.8530000, 2.3400000, null); assertEquals("Rue du Jardinet, Paris, Île-de-France, FR", address); } @@ -41,7 +45,7 @@ public class GeocoderTest { @Test public void testOpenCage() { Geocoder geocoder = new OpenCageGeocoder( - "http://api.opencagedata.com/geocode/v1", "SECRET", null, 0, new AddressFormat()); + client, "http://api.opencagedata.com/geocode/v1", "SECRET", null, 0, new AddressFormat()); String address = geocoder.getAddress(34.116302, -118.051519, null); assertEquals("Charleston Road, California, US", address); } @@ -49,7 +53,7 @@ public class GeocoderTest { @Ignore @Test public void testGeocodeFarm() { - Geocoder geocoder = new GeocodeFarmGeocoder(null, null, 0, new AddressFormat()); + Geocoder geocoder = new GeocodeFarmGeocoder(client, null, null, 0, new AddressFormat()); String address = geocoder.getAddress(34.116302, -118.051519, null); assertEquals("Estrella Avenue, Arcadia, California, United States", address); } @@ -57,7 +61,7 @@ public class GeocoderTest { @Ignore @Test public void testGeocodeXyz() { - Geocoder geocoder = new GeocodeXyzGeocoder(null, 0, new AddressFormat()); + Geocoder geocoder = new GeocodeXyzGeocoder(client, null, 0, new AddressFormat()); String address = geocoder.getAddress(34.116302, -118.051519, null); assertEquals("605 ESTRELLA AVE, ARCADIA, California United States of America, US", address); } @@ -65,7 +69,7 @@ public class GeocoderTest { @Ignore @Test public void testBan() { - Geocoder geocoder = new BanGeocoder(0, new AddressFormat("%f [%d], %c")); + Geocoder geocoder = new BanGeocoder(client, 0, new AddressFormat("%f [%d], %c")); String address = geocoder.getAddress(48.8575, 2.2944, null); assertEquals("8 Avenue Gustave Eiffel 75007 Paris [75, Paris, Île-de-France], FR", address); } @@ -73,7 +77,7 @@ public class GeocoderTest { @Ignore @Test public void testHere() { - Geocoder geocoder = new HereGeocoder(null, "", "", null, 0, new AddressFormat()); + Geocoder geocoder = new HereGeocoder(client, null, "", "", null, 0, new AddressFormat()); String address = geocoder.getAddress(48.8575, 2.2944, null); assertEquals("6 Avenue Gustave Eiffel, Paris, Île-de-France, FRA", address); } @@ -81,7 +85,7 @@ public class GeocoderTest { @Ignore @Test public void testMapmyIndia() { - Geocoder geocoder = new MapmyIndiaGeocoder("", "", 0, new AddressFormat("%f")); + Geocoder geocoder = new MapmyIndiaGeocoder(client, "", "", 0, new AddressFormat("%f")); String address = geocoder.getAddress(28.6129602407977, 77.2294557094574, null); assertEquals("New Delhi, Delhi. 1 m from India Gate pin-110001 (India)", address); } @@ -89,7 +93,7 @@ public class GeocoderTest { @Ignore @Test public void testPositionStack() { - Geocoder geocoder = new PositionStackGeocoder("", 0, new AddressFormat("%f")); + Geocoder geocoder = new PositionStackGeocoder(client, "", 0, new AddressFormat("%f")); String address = geocoder.getAddress(28.6129602407977, 77.2294557094574, null); assertEquals("India Gate, New Delhi, India", address); } @@ -97,7 +101,7 @@ public class GeocoderTest { @Ignore @Test public void testMapbox() { - Geocoder geocoder = new MapboxGeocoder("", 0, new AddressFormat("%f")); + Geocoder geocoder = new MapboxGeocoder(client, "", 0, new AddressFormat("%f")); String address = geocoder.getAddress(40.733, -73.989, null); assertEquals("120 East 13th Street, New York, New York 10003, United States", address); } @@ -105,7 +109,7 @@ public class GeocoderTest { @Ignore @Test public void testMapTiler() { - Geocoder geocoder = new MapTilerGeocoder("", 0, new AddressFormat()); + Geocoder geocoder = new MapTilerGeocoder(client, "", 0, new AddressFormat()); String address = geocoder.getAddress(40.733, -73.989, null); assertEquals("East 13th Street, New York City, New York, United States", address); } @@ -113,7 +117,7 @@ public class GeocoderTest { @Ignore @Test public void testGeoapify() { - Geocoder geocoder = new GeoapifyGeocoder("", null, 0, new AddressFormat()); + Geocoder geocoder = new GeoapifyGeocoder(client, "", null, 0, new AddressFormat()); String address = geocoder.getAddress(40.733, -73.989, null); assertEquals("114 East 13th Street, New York, New York, US", address); } diff --git a/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java b/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java index 2729052d6..1ceac41cc 100644 --- a/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java +++ b/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java @@ -6,19 +6,24 @@ import org.traccar.BaseTest; import org.traccar.model.CellTower; import org.traccar.model.Network; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public class GeolocationProviderTest extends BaseTest { + private final Client client = ClientBuilder.newClient(); + @Ignore @Test public void test() throws Exception { - testLocationProvider(); + testMozilla(); } - public void testLocationProvider() throws Exception { - MozillaGeolocationProvider provider = new MozillaGeolocationProvider(null); + public void testMozilla() throws Exception { + MozillaGeolocationProvider provider = new MozillaGeolocationProvider(client, null); Network network = new Network(CellTower.from(208, 1, 2, 1234567)); diff --git a/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java b/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java index dcac78f80..aa0be23cf 100644 --- a/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java +++ b/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java @@ -3,19 +3,24 @@ package org.traccar.speedlimit; import org.junit.Ignore; import org.junit.Test; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public class OverpassSpeedLimitProviderTest { + private final Client client = ClientBuilder.newClient(); + @Ignore @Test public void test() throws Exception { - testLocationProvider(); + testOverpass(); } - public void testLocationProvider() throws Exception { - SpeedLimitProvider provider = new OverpassSpeedLimitProvider("http://8.8.8.8/api/interpreter"); + public void testOverpass() throws Exception { + SpeedLimitProvider provider = new OverpassSpeedLimitProvider(client, "http://8.8.8.8/api/interpreter"); provider.getSpeedLimit(34.74767, -82.48098, new SpeedLimitProvider.SpeedLimitProviderCallback() { @Override -- cgit v1.2.3 From 8e544be128f7713fecfe91ff08f16044c64bf238 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 15:05:46 -0700 Subject: Clean up unit tests --- src/test/java/org/traccar/geolocation/GeolocationProviderTest.java | 4 ---- .../java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java b/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java index 1ceac41cc..876b6b688 100644 --- a/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java +++ b/src/test/java/org/traccar/geolocation/GeolocationProviderTest.java @@ -18,10 +18,6 @@ public class GeolocationProviderTest extends BaseTest { @Ignore @Test - public void test() throws Exception { - testMozilla(); - } - public void testMozilla() throws Exception { MozillaGeolocationProvider provider = new MozillaGeolocationProvider(client, null); diff --git a/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java b/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java index aa0be23cf..202983f1e 100644 --- a/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java +++ b/src/test/java/org/traccar/speedlimit/OverpassSpeedLimitProviderTest.java @@ -15,10 +15,6 @@ public class OverpassSpeedLimitProviderTest { @Ignore @Test - public void test() throws Exception { - testOverpass(); - } - public void testOverpass() throws Exception { SpeedLimitProvider provider = new OverpassSpeedLimitProvider(client, "http://8.8.8.8/api/interpreter"); -- cgit v1.2.3 From 9c9e62bdba68a1f1d29cd5082ffd47eb1f46dab9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 15:50:37 -0700 Subject: Fix injection --- src/main/java/org/traccar/MainModule.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 2c88dbc13..ed54853ed 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -117,6 +117,11 @@ public class MainModule extends AbstractModule { return Context.getDataManager(); } + @Provides + public static UsersManager provideUsersManager() { + return Context.getUsersManager(); + } + @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); -- cgit v1.2.3 From 0d7985bd502ae106c5c7afcd2b8263058b090e5f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 16:22:29 -0700 Subject: Another injection fix --- src/main/java/org/traccar/MainModule.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index ed54853ed..0b3275cfc 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,6 +30,7 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; +import org.traccar.database.NotificationManager; import org.traccar.database.UsersManager; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; @@ -122,6 +123,11 @@ public class MainModule extends AbstractModule { return Context.getUsersManager(); } + @Provides + public static NotificationManager provideNotificationManager() { + return Context.getNotificationManager(); + } + @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); -- cgit v1.2.3 From 69d634fb0723ca4dced2f15ea432b4eb59d11d8e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 11 Jun 2022 19:09:42 -0700 Subject: Add server overlay URL --- schema/changelog-5.1.xml | 4 ++++ src/main/java/org/traccar/model/Server.java | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/schema/changelog-5.1.xml b/schema/changelog-5.1.xml index 26c2088b9..d5a8bc1fe 100644 --- a/schema/changelog-5.1.xml +++ b/schema/changelog-5.1.xml @@ -12,6 +12,10 @@ + + + + diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index c5640fb97..ee7f7069a 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -85,6 +85,16 @@ public class Server extends ExtendedModel implements UserRestrictions { this.mapUrl = mapUrl; } + private String overlayUrl; + + public String getOverlayUrl() { + return overlayUrl; + } + + public void setOverlayUrl(String overlayUrl) { + this.overlayUrl = overlayUrl; + } + private double latitude; public double getLatitude() { -- cgit v1.2.3 From 62680cbdc4c26e9729aad3c768e5680b27b91e64 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 12 Jun 2022 10:40:53 -0700 Subject: Revert JSR353 removal --- build.gradle | 1 + src/main/java/org/traccar/MainModule.java | 2 ++ 2 files changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 46227d1ff..8c196043a 100644 --- a/build.gradle +++ b/build.gradle @@ -63,6 +63,7 @@ dependencies { implementation "org.glassfish.jersey.inject:jersey-hk2:$jerseyVersion" implementation "org.glassfish.hk2:guice-bridge:2.6.1" // same version as jersey-hk2 implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" implementation "org.liquibase:liquibase-core:4.7.0" implementation "com.sun.mail:javax.mail:1.6.2" implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 0b3275cfc..73fe0c460 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -17,6 +17,7 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr353.JSR353Module; import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Provides; @@ -98,6 +99,7 @@ public class MainModule extends AbstractModule { if (config.getBoolean(Keys.WEB_SANITIZE)) { objectMapper.registerModule(new SanitizerModule()); } + objectMapper.registerModule(new JSR353Module()); objectMapper.setConfig(objectMapper .getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); return objectMapper; -- cgit v1.2.3 From 75044332bebdd8bf3d77431a7008d617dc5f5986 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 12 Jun 2022 10:41:13 -0700 Subject: Update debug config --- debug.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/debug.xml b/debug.xml index 9851232a8..73576b20b 100644 --- a/debug.xml +++ b/debug.xml @@ -7,6 +7,7 @@ ./setup/default.xml ./traccar-web/web + false true true -- cgit v1.2.3 From e894c17cf14addb729a6c51712ef672cc2cd160b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 17:19:15 -0700 Subject: Refactor getPositions method --- .../org/traccar/api/resource/PositionResource.java | 10 +++++++--- src/main/java/org/traccar/database/DataManager.java | 9 --------- .../java/org/traccar/helper/model/PositionUtil.java | 19 +++++++++++++++++++ .../java/org/traccar/reports/RouteReportProvider.java | 11 +++++++---- .../java/org/traccar/reports/StopsReportProvider.java | 8 ++++++-- .../org/traccar/reports/SummaryReportProvider.java | 10 ++++++---- .../java/org/traccar/reports/TripsReportProvider.java | 14 ++++++-------- 7 files changed, 51 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 2618a04cb..ae948ee14 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -17,9 +17,13 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Position; import org.traccar.model.UserRestrictions; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -29,7 +33,6 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.List; @@ -57,9 +60,10 @@ public class PositionResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); if (from != null && to != null) { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); - return Context.getDataManager().getPositions(deviceId, from, to); + return PositionUtil.getPositions(storage, deviceId, from, to); } else { - return Collections.singleton(Context.getDeviceManager().getLastPosition(deviceId)); + return storage.getObjects(Position.class, new Request( + new Columns.All(), new Condition.LatestPositions(deviceId))); } } } diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 556f1e348..93c6861e6 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -176,15 +176,6 @@ public class DataManager { new Condition.Equals("id", "id"))); } - public Collection getPositions(long deviceId, Date from, Date to) throws StorageException { - return storage.getObjects(Position.class, new Request( - new Columns.All(), - new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), - new Condition.Between("fixTime", "from", from, "to", to)), - new Order("fixTime"))); - } - public Position getPrecedingPosition(long deviceId, Date date) throws StorageException { return storage.getObject(Position.class, new Request( new Columns.All(), diff --git a/src/main/java/org/traccar/helper/model/PositionUtil.java b/src/main/java/org/traccar/helper/model/PositionUtil.java index 644517dac..566e31bc5 100644 --- a/src/main/java/org/traccar/helper/model/PositionUtil.java +++ b/src/main/java/org/traccar/helper/model/PositionUtil.java @@ -17,6 +17,15 @@ package org.traccar.helper.model; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; + +import java.util.Date; +import java.util.List; public final class PositionUtil { @@ -41,4 +50,14 @@ public final class PositionUtil { return distance; } + public static List getPositions( + Storage storage, long deviceId, Date from, Date to) throws StorageException { + return storage.getObjects(Position.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Between("fixTime", "from", from, "to", to)), + new Order("fixTime"))); + } + } diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 136a154aa..dbbf0906d 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -18,11 +18,13 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -37,10 +39,12 @@ import java.util.Date; public class RouteReportProvider { private final ReportUtils reportUtils; + private final Storage storage; @Inject - public RouteReportProvider(ReportUtils reportUtils) { + public RouteReportProvider(ReportUtils reportUtils, Storage storage) { this.reportUtils = reportUtils; + this.storage = storage; } public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, @@ -49,7 +53,7 @@ public class RouteReportProvider { ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - result.addAll(Context.getDataManager().getPositions(deviceId, from, to)); + result.addAll(PositionUtil.getPositions(storage, deviceId, from, to)); } return result; } @@ -62,8 +66,7 @@ public class RouteReportProvider { ArrayList sheetNames = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection positions = Context.getDataManager() - .getPositions(deviceId, from, to); + var positions = PositionUtil.getPositions(storage, deviceId, from, to); DeviceReportSection deviceRoutes = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); deviceRoutes.setDeviceName(device.getName()); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 807a6133b..534ab7742 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -18,11 +18,13 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -37,17 +39,19 @@ import java.util.Date; public class StopsReportProvider { private final ReportUtils reportUtils; + private final Storage storage; @Inject - public StopsReportProvider(ReportUtils reportUtils) { + public StopsReportProvider(ReportUtils reportUtils, Storage storage) { this.reportUtils = reportUtils; + this.storage = storage; } private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); return reportUtils.detectTripsAndStops( - Context.getDataManager().getPositions(deviceId, from, to), ignoreOdometer, StopReportItem.class); + PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, StopReportItem.class); } public Collection getObjects( diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 28abe790b..25d558480 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -25,6 +25,7 @@ import org.traccar.helper.model.UserUtil; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReportItem; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -41,11 +42,13 @@ public class SummaryReportProvider { private final ReportUtils reportUtils; private final PermissionsService permissionsService; + private final Storage storage; @Inject - public SummaryReportProvider(ReportUtils reportUtils, PermissionsService permissionsService) { + public SummaryReportProvider(ReportUtils reportUtils, PermissionsService permissionsService, Storage storage) { this.reportUtils = reportUtils; this.permissionsService = permissionsService; + this.storage = storage; } private SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { @@ -111,9 +114,8 @@ public class SummaryReportProvider { private Collection calculateSummaryResults( long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { - ArrayList positions = new ArrayList<>(Context.getDataManager().getPositions(deviceId, from, to)); - - ArrayList results = new ArrayList<>(); + var positions = PositionUtil.getPositions(storage, deviceId, from, to); + var results = new ArrayList(); if (daily && !positions.isEmpty()) { int startIndex = 0; int startDay = getDay(userId, positions.iterator().next().getFixTime()); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 5e598cb50..a8e0e3dde 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -18,14 +18,13 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; -import org.traccar.Main; -import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -40,21 +39,20 @@ import java.util.Date; public class TripsReportProvider { private final ReportUtils reportUtils; + private final Storage storage; @Inject - public TripsReportProvider(ReportUtils reportUtils) { + public TripsReportProvider(ReportUtils reportUtils, Storage storage) { this.reportUtils = reportUtils; + this.storage = storage; } private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { boolean ignoreOdometer = Context.getDeviceManager() .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class); - DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class); - return reportUtils.detectTripsAndStops( - Context.getDataManager().getPositions(deviceId, from, to), ignoreOdometer, TripReportItem.class); + PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, TripReportItem.class); } public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, -- cgit v1.2.3 From 8569e396f7bdafd49a974b35a2e83a57164c6c62 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 18:49:01 -0700 Subject: Remove report template path key --- .../java/org/traccar/reports/EventsReportProvider.java | 14 ++++++++++---- .../java/org/traccar/reports/RouteReportProvider.java | 14 ++++++++++---- .../java/org/traccar/reports/StopsReportProvider.java | 14 ++++++++++---- .../java/org/traccar/reports/SummaryReportProvider.java | 15 +++++++++++---- .../java/org/traccar/reports/TripsReportProvider.java | 14 ++++++++++---- 5 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 6de313a13..91d061c65 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -18,6 +18,8 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -28,10 +30,12 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -40,10 +44,12 @@ import java.util.Iterator; public class EventsReportProvider { + private final Config config; private final ReportUtils reportUtils; @Inject - public EventsReportProvider(ReportUtils reportUtils) { + public EventsReportProvider(Config config, ReportUtils reportUtils) { + this.config = config; this.reportUtils = reportUtils; } @@ -120,9 +126,9 @@ public class EventsReportProvider { deviceEvents.setObjects(events); devicesEvents.add(deviceEvents); } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) { + + File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "events.xlsx").toFile(); + try (InputStream inputStream = new FileInputStream(file)) { var context = reportUtils.initializeContext(userId); context.putVar("devices", devicesEvents); context.putVar("sheetNames", sheetNames); diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index dbbf0906d..b1a806960 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -18,6 +18,8 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; @@ -28,21 +30,25 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Date; public class RouteReportProvider { + private final Config config; private final ReportUtils reportUtils; private final Storage storage; @Inject - public RouteReportProvider(ReportUtils reportUtils, Storage storage) { + public RouteReportProvider(Config config, ReportUtils reportUtils, Storage storage) { + this.config = config; this.reportUtils = reportUtils; this.storage = storage; } @@ -80,9 +86,9 @@ public class RouteReportProvider { deviceRoutes.setObjects(positions); devicesRoutes.add(deviceRoutes); } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) { + + File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "route.xlsx").toFile(); + try (InputStream inputStream = new FileInputStream(file)) { var context = reportUtils.initializeContext(userId); context.putVar("devices", devicesRoutes); context.putVar("sheetNames", sheetNames); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 534ab7742..a6a9a94cc 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -18,6 +18,8 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; @@ -28,21 +30,25 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Date; public class StopsReportProvider { + private final Config config; private final ReportUtils reportUtils; private final Storage storage; @Inject - public StopsReportProvider(ReportUtils reportUtils, Storage storage) { + public StopsReportProvider(Config config, ReportUtils reportUtils, Storage storage) { + this.config = config; this.reportUtils = reportUtils; this.storage = storage; } @@ -88,9 +94,9 @@ public class StopsReportProvider { deviceStops.setObjects(stops); devicesStops.add(deviceStops); } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/stops.xlsx")) { + + File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "stops.xlsx").toFile(); + try (InputStream inputStream = new FileInputStream(file)) { var context = reportUtils.initializeContext(userId); context.putVar("devices", devicesStops); context.putVar("sheetNames", sheetNames); diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 25d558480..68976b987 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -19,6 +19,8 @@ package org.traccar.reports; import org.jxls.util.JxlsHelper; import org.traccar.Context; import org.traccar.api.security.PermissionsService; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.UnitsConverter; import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; @@ -29,10 +31,12 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; @@ -40,12 +44,15 @@ import java.util.Date; public class SummaryReportProvider { + private final Config config; private final ReportUtils reportUtils; private final PermissionsService permissionsService; private final Storage storage; @Inject - public SummaryReportProvider(ReportUtils reportUtils, PermissionsService permissionsService, Storage storage) { + public SummaryReportProvider( + Config config, ReportUtils reportUtils, PermissionsService permissionsService, Storage storage) { + this.config = config; this.reportUtils = reportUtils; this.permissionsService = permissionsService; this.storage = storage; @@ -157,9 +164,9 @@ public class SummaryReportProvider { Date from, Date to, boolean daily) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { + + File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "summary.xlsx").toFile(); + try (InputStream inputStream = new FileInputStream(file)) { var context = reportUtils.initializeContext(userId); context.putVar("summaries", summaries); context.putVar("from", from); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index a8e0e3dde..bff559664 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -18,6 +18,8 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; import org.traccar.Context; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Group; @@ -28,21 +30,25 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Date; public class TripsReportProvider { + private final Config config; private final ReportUtils reportUtils; private final Storage storage; @Inject - public TripsReportProvider(ReportUtils reportUtils, Storage storage) { + public TripsReportProvider(Config config, ReportUtils reportUtils, Storage storage) { + this.config = config; this.reportUtils = reportUtils; this.storage = storage; } @@ -88,9 +94,9 @@ public class TripsReportProvider { deviceTrips.setObjects(trips); devicesTrips.add(deviceTrips); } - String templatePath = Context.getConfig().getString("report.templatesPath", - "templates/export/"); - try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) { + + File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "trips.xlsx").toFile(); + try (InputStream inputStream = new FileInputStream(file)) { var context = reportUtils.initializeContext(userId); context.putVar("devices", devicesTrips); context.putVar("sheetNames", sheetNames); -- cgit v1.2.3 From a4f47f67b654cbfd59a134ed3a621f75b35ad7af Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 18:55:34 -0700 Subject: Refactor getEvents method --- .../java/org/traccar/database/DataManager.java | 10 ---------- .../org/traccar/reports/EventsReportProvider.java | 23 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 93c6861e6..4fd0cd8c1 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -31,7 +31,6 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Event; import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; @@ -205,15 +204,6 @@ public class DataManager { return storage.getObject(Server.class, new Request(new Columns.All())); } - public Collection getEvents(long deviceId, Date from, Date to) throws StorageException { - return storage.getObjects(Event.class, new Request( - new Columns.All(), - new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), - new Condition.Between("eventTime", "from", from, "to", to)), - new Order("eventTime"))); - } - public Collection getStatistics(Date from, Date to) throws StorageException { return storage.getObjects(Statistics.class, new Request( new Columns.All(), diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 91d061c65..5148695a9 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -27,7 +27,12 @@ import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -41,16 +46,28 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; +import java.util.List; public class EventsReportProvider { private final Config config; private final ReportUtils reportUtils; + private final Storage storage; @Inject - public EventsReportProvider(Config config, ReportUtils reportUtils) { + public EventsReportProvider(Config config, ReportUtils reportUtils, Storage storage) { this.config = config; this.reportUtils = reportUtils; + this.storage = storage; + } + + private List getEvents(long deviceId, Date from, Date to) throws StorageException { + return storage.getObjects(Event.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Between("eventTime", "from", from, "to", to)), + new Order("eventTime"))); } public Collection getObjects( @@ -60,7 +77,7 @@ public class EventsReportProvider { ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection events = Context.getDataManager().getEvents(deviceId, from, to); + Collection events = getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Event event : events) { if (all || types.contains(event.getType())) { @@ -87,7 +104,7 @@ public class EventsReportProvider { HashMap maintenanceNames = new HashMap<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection events = Context.getDataManager().getEvents(deviceId, from, to); + Collection events = getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Iterator iterator = events.iterator(); iterator.hasNext();) { Event event = iterator.next(); -- cgit v1.2.3 From 6433ec663ec79196714dcd99939cdddf81f77a7a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 18:57:19 -0700 Subject: Refactor getStatistics method --- .../java/org/traccar/api/resource/StatisticsResource.java | 14 ++++++++++---- src/main/java/org/traccar/database/DataManager.java | 8 -------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/StatisticsResource.java b/src/main/java/org/traccar/api/resource/StatisticsResource.java index 5c0734877..1f2296f28 100644 --- a/src/main/java/org/traccar/api/resource/StatisticsResource.java +++ b/src/main/java/org/traccar/api/resource/StatisticsResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,13 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.Statistics; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -37,8 +40,11 @@ public class StatisticsResource extends BaseResource { @GET public Collection get( @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { - Context.getPermissionsManager().checkAdmin(getUserId()); - return Context.getDataManager().getStatistics(from, to); + permissionsService.checkAdmin(getUserId()); + return storage.getObjects(Statistics.class, new Request( + new Columns.All(), + new Condition.Between("captureTime", "from", from, "to", to), + new Order("captureTime"))); } } diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 4fd0cd8c1..8ed907fdd 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -34,7 +34,6 @@ import org.traccar.model.Device; import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; -import org.traccar.model.Statistics; import org.traccar.model.User; import org.traccar.storage.DatabaseStorage; import org.traccar.storage.Storage; @@ -204,13 +203,6 @@ public class DataManager { return storage.getObject(Server.class, new Request(new Columns.All())); } - public Collection getStatistics(Date from, Date to) throws StorageException { - return storage.getObjects(Statistics.class, new Request( - new Columns.All(), - new Condition.Between("captureTime", "from", from, "to", to), - new Order("captureTime"))); - } - public Collection getPermissions(Class owner, Class property) throws StorageException, ClassNotFoundException { return storage.getPermissions(owner, property); -- cgit v1.2.3 From dd2594ddce22e105a6d9cb356c3c22c3227e58f9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 19:03:37 -0700 Subject: Remove data manager methods --- .../java/org/traccar/api/resource/EventResource.java | 6 +++++- .../org/traccar/api/resource/PermissionsResource.java | 6 ++---- .../java/org/traccar/api/resource/PositionResource.java | 3 ++- src/main/java/org/traccar/api/resource/UserResource.java | 3 ++- src/main/java/org/traccar/database/DataManager.java | 16 ---------------- 5 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index 38b101b25..eb373946a 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -19,6 +19,9 @@ import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.Event; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -37,7 +40,8 @@ public class EventResource extends BaseResource { @Path("{id}") @GET public Event get(@PathParam("id") long id) throws StorageException { - Event event = Context.getDataManager().getObject(Event.class, id); + Event event = storage.getObject(Event.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", id))); if (event == null) { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index a4db6754c..36ee0c213 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -70,8 +70,7 @@ public class PermissionsResource extends BaseResource { for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); checkPermission(permission, true); - Context.getDataManager().linkObject(permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId(), true); + storage.addPermission(permission); cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), @@ -96,8 +95,7 @@ public class PermissionsResource extends BaseResource { for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); checkPermission(permission, false); - Context.getDataManager().linkObject(permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId(), false); + storage.removePermission(permission); cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index ae948ee14..2c0724df8 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -49,7 +49,8 @@ public class PositionResource extends BaseResource { if (!positionIds.isEmpty()) { ArrayList positions = new ArrayList<>(); for (Long positionId : positionIds) { - Position position = Context.getDataManager().getObject(Position.class, positionId); + Position position = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", positionId))); Context.getPermissionsManager().checkDevice(getUserId(), position.getDeviceId()); positions.add(position); } diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 83bb8fd0b..84f41ca1a 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -21,6 +21,7 @@ import org.traccar.config.Keys; import org.traccar.database.UsersManager; import org.traccar.helper.LogAction; import org.traccar.model.ManagedUser; +import org.traccar.model.Permission; import org.traccar.model.User; import org.traccar.storage.StorageException; @@ -86,7 +87,7 @@ public class UserResource extends BaseObjectResource { Context.getUsersManager().addItem(entity); LogAction.create(getUserId(), entity); if (Context.getPermissionsManager().getUserManager(getUserId())) { - Context.getDataManager().linkObject(User.class, getUserId(), ManagedUser.class, entity.getId(), true); + storage.addPermission(new Permission(User.class, getUserId(), ManagedUser.class, entity.getId())); LogAction.link(getUserId(), User.class, getUserId(), ManagedUser.class, entity.getId()); } Context.getUsersManager().refreshUserItems(); diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 8ed907fdd..fd45a0321 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -208,22 +208,6 @@ public class DataManager { return storage.getPermissions(owner, property); } - public void linkObject( - Class owner, long ownerId, - Class property, long propertyId, boolean link) throws StorageException { - if (link) { - storage.addPermission(new Permission(owner, ownerId, property, propertyId)); - } else { - storage.removePermission(new Permission(owner, ownerId, property, propertyId)); - } - } - - public T getObject(Class clazz, long entityId) throws StorageException { - return storage.getObject(clazz, new Request( - new Columns.All(), - new Condition.Equals("id", "id", entityId))); - } - public Collection getObjects(Class clazz) throws StorageException { return storage.getObjects(clazz, new Request(new Columns.All())); } -- cgit v1.2.3 From e43169b2677ea9f07154247ce7ff726d046e59e2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 13 Jun 2022 19:16:46 -0700 Subject: Refactor position resource --- .../org/traccar/api/resource/PositionResource.java | 28 +++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 2c0724df8..099d97632 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -15,10 +15,12 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.model.PositionUtil; +import org.traccar.model.BaseModel; +import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -35,6 +37,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; @Path("positions") @Produces(MediaType.APPLICATION_JSON) @@ -47,18 +50,16 @@ public class PositionResource extends BaseResource { @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { if (!positionIds.isEmpty()) { - ArrayList positions = new ArrayList<>(); - for (Long positionId : positionIds) { + var positions = new ArrayList(); + for (long positionId : positionIds) { Position position = storage.getObject(Position.class, new Request( new Columns.All(), new Condition.Equals("id", "id", positionId))); - Context.getPermissionsManager().checkDevice(getUserId(), position.getDeviceId()); + permissionsService.checkPermission(Device.class, getUserId(), position.getDeviceId()); positions.add(position); } return positions; - } else if (deviceId == 0) { - return Context.getDeviceManager().getInitialState(getUserId()); - } else { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + } else if (deviceId > 0) { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); if (from != null && to != null) { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return PositionUtil.getPositions(storage, deviceId, from, to); @@ -66,6 +67,17 @@ public class PositionResource extends BaseResource { return storage.getObjects(Position.class, new Request( new Columns.All(), new Condition.LatestPositions(deviceId))); } + } else { + var devices = storage.getObjects(Device.class, new Request( + new Columns.Include("id"), + new Condition.Permission(User.class, getUserId(), Device.class))); + var deviceIds = devices.stream().map(BaseModel::getId).collect(Collectors.toUnmodifiableSet()); + + var positions = storage.getObjects(Position.class, new Request( + new Columns.All(), new Condition.LatestPositions())); + return positions.stream() + .filter(position -> deviceIds.contains(position.getDeviceId())) + .collect(Collectors.toList()); } } -- cgit v1.2.3 From 415ba3ddb0f770b829c997beb3e575ffb6e195ec Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Jun 2022 17:06:44 -0700 Subject: Inject connection manager --- schema/changelog-5.1.xml | 4 ++ src/main/java/org/traccar/Context.java | 11 +--- src/main/java/org/traccar/MainEventHandler.java | 8 ++- src/main/java/org/traccar/MainModule.java | 6 -- src/main/java/org/traccar/api/AsyncSocket.java | 8 ++- .../java/org/traccar/api/AsyncSocketServlet.java | 7 +- .../java/org/traccar/database/DeviceManager.java | 11 ++-- .../org/traccar/session/ConnectionManager.java | 76 ++++++++++++++++++---- 8 files changed, 91 insertions(+), 40 deletions(-) diff --git a/schema/changelog-5.1.xml b/schema/changelog-5.1.xml index d5a8bc1fe..e68325625 100644 --- a/schema/changelog-5.1.xml +++ b/schema/changelog-5.1.xml @@ -12,6 +12,10 @@ + + + + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 62ad01c24..a66cde464 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -78,12 +78,6 @@ public final class Context { return deviceManager; } - private static ConnectionManager connectionManager; - - public static ConnectionManager getConnectionManager() { - return connectionManager; - } - private static PermissionsManager permissionsManager; public static PermissionsManager getPermissionsManager() { @@ -114,15 +108,14 @@ public final class Context { if (dataManager != null) { usersManager = new UsersManager(dataManager); groupsManager = new GroupsManager(dataManager); - deviceManager = new DeviceManager(dataManager); + deviceManager = new DeviceManager( + config, dataManager, Main.getInjector().getInstance(ConnectionManager.class)); } identityManager = deviceManager; permissionsManager = new PermissionsManager(dataManager, usersManager); - connectionManager = new ConnectionManager(); - initEventsModule(); } diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index bb84a09d2..d4a0fae6c 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -28,6 +28,7 @@ import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.helper.NetworkUtil; import org.traccar.model.Position; +import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; @@ -44,8 +45,11 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Set connectionlessProtocols = new HashSet<>(); private final Set logAttributes = new LinkedHashSet<>(); + private final ConnectionManager connectionManager; + @Inject - public MainEventHandler() { + public MainEventHandler(ConnectionManager connectionManager) { + this.connectionManager = connectionManager; String connectionlessProtocolList = Context.getConfig().getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split("[, ]"))); @@ -132,7 +136,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName())) { - Context.getConnectionManager().deviceDisconnected(ctx.channel()); + connectionManager.deviceDisconnected(ctx.channel()); } } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 73fe0c460..306bc9e7b 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -35,7 +35,6 @@ import org.traccar.database.NotificationManager; import org.traccar.database.UsersManager; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; -import org.traccar.session.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; @@ -135,11 +134,6 @@ public class MainModule extends AbstractModule { return Context.getIdentityManager(); } - @Provides - public static ConnectionManager provideConnectionManager() { - return Context.getConnectionManager(); - } - @Provides public static Client provideClient() { return ClientBuilder.newClient().register( diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java index 2b866176b..3239d36c4 100644 --- a/src/main/java/org/traccar/api/AsyncSocket.java +++ b/src/main/java/org/traccar/api/AsyncSocket.java @@ -41,10 +41,12 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U private static final String KEY_EVENTS = "events"; private final ObjectMapper objectMapper; + private final ConnectionManager connectionManager; private final long userId; - public AsyncSocket(ObjectMapper objectMapper, long userId) { + public AsyncSocket(ObjectMapper objectMapper, ConnectionManager connectionManager, long userId) { this.objectMapper = objectMapper; + this.connectionManager = connectionManager; this.userId = userId; } @@ -56,14 +58,14 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U data.put(KEY_POSITIONS, Context.getDeviceManager().getInitialState(userId)); sendData(data); - Context.getConnectionManager().addListener(userId, this); + connectionManager.addListener(userId, this); } @Override public void onWebSocketClose(int statusCode, String reason) { super.onWebSocketClose(statusCode, reason); - Context.getConnectionManager().removeListener(userId, this); + connectionManager.removeListener(userId, this); } @Override diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 4e55dfebf..317ec469e 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -21,6 +21,7 @@ import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.traccar.Context; import org.traccar.api.resource.SessionResource; import org.traccar.config.Keys; +import org.traccar.session.ConnectionManager; import javax.inject.Inject; import javax.servlet.http.HttpSession; @@ -29,10 +30,12 @@ import java.time.Duration; public class AsyncSocketServlet extends JettyWebSocketServlet { private final ObjectMapper objectMapper; + private final ConnectionManager connectionManager; @Inject - public AsyncSocketServlet(ObjectMapper objectMapper) { + public AsyncSocketServlet(ObjectMapper objectMapper, ConnectionManager connectionManager) { this.objectMapper = objectMapper; + this.connectionManager = connectionManager; } @Override @@ -41,7 +44,7 @@ public class AsyncSocketServlet extends JettyWebSocketServlet { factory.setCreator((req, resp) -> { if (req.getSession() != null) { long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); - return new AsyncSocket(objectMapper, userId); + return new AsyncSocket(objectMapper, connectionManager, userId); } else { return null; } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 20f179f2e..973cf3f68 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -32,6 +32,7 @@ import org.traccar.Context; import org.traccar.config.Keys; import org.traccar.model.Command; import org.traccar.model.Device; +import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceState; import org.traccar.model.DeviceAccumulators; import org.traccar.model.Group; @@ -45,6 +46,7 @@ public class DeviceManager extends BaseObjectManager implements Identity private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); private final Config config; + private final ConnectionManager connectionManager; private final long dataRefreshDelay; private Map devicesByUniqueId; @@ -54,9 +56,10 @@ public class DeviceManager extends BaseObjectManager implements Identity private final Map deviceStates = new ConcurrentHashMap<>(); - public DeviceManager(DataManager dataManager) { + public DeviceManager(Config config, DataManager dataManager, ConnectionManager connectionManager) { super(dataManager, Device.class); - this.config = Context.getConfig(); + this.config = config; + this.connectionManager = connectionManager; try { writeLock(); if (devicesByUniqueId == null) { @@ -287,9 +290,7 @@ public class DeviceManager extends BaseObjectManager implements Identity positions.put(position.getDeviceId(), position); - if (Context.getConnectionManager() != null) { - Context.getConnectionManager().updatePosition(position); - } + connectionManager.updatePosition(position); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index e01a568aa..ab3c36734 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.Main; import org.traccar.Protocol; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; @@ -30,8 +31,14 @@ import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; +import javax.inject.Inject; +import javax.inject.Singleton; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Date; @@ -42,6 +49,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +@Singleton public class ConnectionManager { private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); @@ -52,18 +60,23 @@ public class ConnectionManager { private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); + private final Config config; private final CacheManager cacheManager; + private final Storage storage; + private final Timer timer; private final Map> listeners = new ConcurrentHashMap<>(); private final Map timeouts = new ConcurrentHashMap<>(); - private final Timer timer; - - public ConnectionManager() { - deviceTimeout = Context.getConfig().getLong(Keys.STATUS_TIMEOUT) * 1000; - updateDeviceState = Context.getConfig().getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); - timer = Main.getInjector().getInstance(Timer.class); - cacheManager = Main.getInjector().getInstance(CacheManager.class); + @Inject + public ConnectionManager( + Config config, CacheManager cacheManager, Storage storage, Timer timer) { + this.config = config; + this.cacheManager = cacheManager; + this.storage = storage; + this.timer = timer; + deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT) * 1000; + updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); } public DeviceSession getDeviceSession(long deviceId) { @@ -91,7 +104,8 @@ public class ConnectionManager { Device device = null; try { for (String uniqueId : uniqueIds) { - device = Context.getIdentityManager().getByUniqueId(uniqueId); + device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); if (device != null) { break; } @@ -100,8 +114,8 @@ public class ConnectionManager { LOGGER.warn("Find device error", e); } - if (device == null && Context.getConfig().getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { - device = Context.getIdentityManager().addUnknownDevice(uniqueIds[0]); + if (device == null && config.getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { + device = addUnknownDevice(uniqueIds[0]); } if (device != null && !device.getDisabled()) { @@ -131,6 +145,34 @@ public class ConnectionManager { } } + private Device addUnknownDevice(String uniqueId) { + Device device = new Device(); + device.setName(uniqueId); + device.setUniqueId(uniqueId); + device.setCategory(config.getString(Keys.DATABASE_REGISTER_UNKNOWN_DEFAULT_CATEGORY)); + + long defaultGroupId = config.getLong(Keys.DATABASE_REGISTER_UNKNOWN_DEFAULT_GROUP_ID); + if (defaultGroupId != 0) { + device.setGroupId(defaultGroupId); + } + + try { + device.setId(storage.addObject(device, new Request(new Columns.Exclude("id")))); + + LOGGER.info("Automatically registered device " + uniqueId); + + if (defaultGroupId != 0) { + Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); + Context.getPermissionsManager().refreshAllExtendedPermissions(); + } + + return device; + } catch (StorageException e) { + LOGGER.warn("Automatic device registration error", e); + return null; + } + } + public void deviceDisconnected(Channel channel) { Endpoint endpoint = new Endpoint(channel, channel.remoteAddress()); Map endpointSessions = sessionsByEndpoint.remove(endpoint); @@ -156,10 +198,18 @@ public class ConnectionManager { } } - public void updateDevice(final long deviceId, String status, Date time) { - Device device = Context.getIdentityManager().getById(deviceId); + public void updateDevice(long deviceId, String status, Date time) { + Device device = cacheManager.getObject(Device.class, deviceId); if (device == null) { - return; + try { + device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId))); + } catch (StorageException e) { + LOGGER.warn("Failed to get device", e); + } + if (device == null) { + return; + } } String oldStatus = device.getStatus(); -- cgit v1.2.3 From 0d5c7606c73d84aab44f69936ab62afa0b68939b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 14 Jun 2022 18:50:48 -0700 Subject: Refactor notification manager --- src/main/java/org/traccar/Context.java | 26 ----- src/main/java/org/traccar/MainModule.java | 8 +- .../java/org/traccar/api/BaseObjectResource.java | 10 -- .../traccar/api/resource/NotificationResource.java | 22 +++- .../java/org/traccar/database/DeviceManager.java | 1 - .../traccar/database/ExtendedObjectManager.java | 30 +---- .../org/traccar/database/NotificationManager.java | 126 ++++++++------------- .../org/traccar/database/PermissionsManager.java | 51 --------- .../traccar/handler/events/BaseEventHandler.java | 17 ++- .../org/traccar/notification/EventForwarder.java | 14 +-- .../traccar/notification/NotificatorManager.java | 51 ++++----- .../org/traccar/session/ConnectionManager.java | 9 +- 12 files changed, 116 insertions(+), 249 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index a66cde464..51c420390 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -22,20 +22,14 @@ import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; -import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; import org.traccar.database.UsersManager; -import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.model.Notification; import org.traccar.model.User; -import org.traccar.notification.EventForwarder; -import org.traccar.notification.NotificatorManager; import org.traccar.session.ConnectionManager; -import org.traccar.session.cache.CacheManager; public final class Context { @@ -84,12 +78,6 @@ public final class Context { return permissionsManager; } - private static NotificationManager notificationManager; - - public static NotificationManager getNotificationManager() { - return notificationManager; - } - public static void init(String configFile) throws Exception { try { @@ -116,18 +104,6 @@ public final class Context { permissionsManager = new PermissionsManager(dataManager, usersManager); - initEventsModule(); - - } - - private static void initEventsModule() { - - notificationManager = new NotificationManager( - dataManager, - Main.getInjector().getInstance(CacheManager.class), - Main.getInjector().getInstance(EventForwarder.class), - Main.getInjector().getInstance(NotificatorManager.class), - Main.getInjector().getInstance(Geocoder.class)); } public static BaseObjectManager getManager(Class clazz) { @@ -137,8 +113,6 @@ public final class Context { return (BaseObjectManager) groupsManager; } else if (clazz.equals(User.class)) { return (BaseObjectManager) usersManager; - } else if (clazz.equals(Notification.class)) { - return (BaseObjectManager) notificationManager; } return null; } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 306bc9e7b..dd496e5a4 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -31,7 +31,6 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; -import org.traccar.database.NotificationManager; import org.traccar.database.UsersManager; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; @@ -124,11 +123,6 @@ public class MainModule extends AbstractModule { return Context.getUsersManager(); } - @Provides - public static NotificationManager provideNotificationManager() { - return Context.getNotificationManager(); - } - @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); @@ -301,7 +295,7 @@ public class MainModule extends AbstractModule { public static EventForwarder provideEventForwarder( Config config, Client client, CacheManager cacheManager, UsersManager usersManager) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - return new EventForwarder(config, client, cacheManager, usersManager); + return new EventForwarder(config, client, cacheManager); } return null; } diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index cc930c591..aa777f3f6 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -22,7 +22,6 @@ import org.traccar.database.ExtendedObjectManager; import org.traccar.database.SimpleObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; -import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; @@ -87,7 +86,6 @@ public abstract class BaseObjectResource extends BaseResour ((SimpleObjectManager) manager).refreshUserItems(); } else if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); } return Response.ok(entity).build(); } @@ -112,7 +110,6 @@ public abstract class BaseObjectResource extends BaseResour if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); } return Response.ok(entity).build(); } @@ -145,13 +142,6 @@ public abstract class BaseObjectResource extends BaseResour Context.getDeviceManager().updateDeviceCache(true); } Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - if (baseClass.equals(User.class)) { - Context.getPermissionsManager().refreshAllUsersPermissions(); - } else { - Context.getPermissionsManager().refreshAllExtendedPermissions(); - } - } else if (baseClass.equals(Calendar.class)) { - Context.getNotificationManager().refreshItems(); } return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index 0a95b257a..a42de687d 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -15,7 +15,11 @@ */ package org.traccar.api.resource; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; import javax.inject.Inject; import javax.ws.rs.Consumes; @@ -27,7 +31,8 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.traccar.Context; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.api.ExtendedObjectResource; import org.traccar.model.Event; import org.traccar.model.Notification; @@ -42,6 +47,8 @@ import org.traccar.storage.StorageException; @Consumes(MediaType.APPLICATION_JSON) public class NotificationResource extends ExtendedObjectResource { + private static final Logger LOGGER = LoggerFactory.getLogger(NotificationResource.class); + @Inject private NotificatorManager notificatorManager; @@ -52,7 +59,18 @@ public class NotificationResource extends ExtendedObjectResource { @GET @Path("types") public Collection get() { - return Context.getNotificationManager().getAllNotificationTypes(); + Set types = new HashSet<>(); + Field[] fields = Event.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { + try { + types.add(new Typed(field.get(null).toString())); + } catch (IllegalArgumentException | IllegalAccessException error) { + LOGGER.warn("Get event types error", error); + } + } + } + return types; } @GET diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 973cf3f68..e1d6ad1dd 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -91,7 +91,6 @@ public class DeviceManager extends BaseObjectManager implements Identity if (defaultGroupId != 0) { Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); } return device; diff --git a/src/main/java/org/traccar/database/ExtendedObjectManager.java b/src/main/java/org/traccar/database/ExtendedObjectManager.java index 006ed47b2..fe0ebb96e 100644 --- a/src/main/java/org/traccar/database/ExtendedObjectManager.java +++ b/src/main/java/org/traccar/database/ExtendedObjectManager.java @@ -44,34 +44,6 @@ public abstract class ExtendedObjectManager extends SimpleO refreshExtendedPermissions(); } - public final Set getGroupItems(long groupId) { - try { - readLock(); - Set result = groupItems.get(groupId); - if (result != null) { - return new HashSet<>(result); - } else { - return new HashSet<>(); - } - } finally { - readUnlock(); - } - } - - public final Set getDeviceItems(long deviceId) { - try { - readLock(); - Set result = deviceItems.get(deviceId); - if (result != null) { - return new HashSet<>(result); - } else { - return new HashSet<>(); - } - } finally { - readUnlock(); - } - } - public Set getAllDeviceItems(long deviceId) { try { readLock(); @@ -122,7 +94,7 @@ public abstract class ExtendedObjectManager extends SimpleO .add(devicePermission.getPropertyId()); } - for (Device device : Context.getDeviceManager().getAllDevices()) { + for (Device device : getDataManager().getObjects(Device.class)) { long groupId = device.getGroupId(); while (groupId > 0) { deviceItemsWithGroups diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 3c87aacb2..46b58dd75 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -16,39 +16,36 @@ */ package org.traccar.database; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.geocoder.Geocoder; import org.traccar.model.Calendar; import org.traccar.model.Event; import org.traccar.model.Notification; import org.traccar.model.Position; -import org.traccar.model.Typed; -import org.traccar.model.User; import org.traccar.notification.EventForwarder; import org.traccar.notification.MessageException; import org.traccar.notification.NotificatorManager; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; import javax.annotation.Nullable; +import javax.inject.Inject; +import java.util.Arrays; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; -public class NotificationManager extends ExtendedObjectManager { +public class NotificationManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); + private final Storage storage; private final CacheManager cacheManager; private final EventForwarder eventForwarder; private final NotificatorManager notificatorManager; @@ -56,81 +53,67 @@ public class NotificationManager extends ExtendedObjectManager { private final boolean geocodeOnRequest; + @Inject public NotificationManager( - DataManager dataManager, CacheManager cacheManager, @Nullable EventForwarder eventForwarder, + Config config, Storage storage, CacheManager cacheManager, @Nullable EventForwarder eventForwarder, NotificatorManager notificatorManager, @Nullable Geocoder geocoder) { - super(dataManager, Notification.class); + this.storage = storage; this.cacheManager = cacheManager; this.eventForwarder = eventForwarder; this.notificatorManager = notificatorManager; this.geocoder = geocoder; - geocodeOnRequest = Context.getConfig().getBoolean(Keys.GEOCODER_ON_REQUEST); - } - - private Set getEffectiveNotifications(long userId, long deviceId, Date time) { - Set result = new HashSet<>(); - Set deviceNotifications = getAllDeviceItems(deviceId); - for (long itemId : getUserItems(userId)) { - if (getById(itemId).getAlways() || deviceNotifications.contains(itemId)) { - long calendarId = getById(itemId).getCalendarId(); - Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; - if (calendar == null || calendar.checkMoment(time)) { - result.add(itemId); - } - } - } - return result; + geocodeOnRequest = config.getBoolean(Keys.GEOCODER_ON_REQUEST); } public void updateEvent(Event event, Position position) { try { - getDataManager().addObject(event); + event.setId(storage.addObject(event, new Request(new Columns.Exclude("id")))); } catch (StorageException error) { LOGGER.warn("Event save error", error); } - long deviceId = event.getDeviceId(); - Set users = Context.getPermissionsManager().getDeviceUsers(deviceId); - Set usersToForward = new HashSet<>(); - for (long userId : users) { - usersToForward.add(userId); - final Set notificators = new HashSet<>(); - for (long notificationId : getEffectiveNotifications(userId, deviceId, event.getEventTime())) { - Notification notification = getById(notificationId); - if (getById(notificationId).getType().equals(event.getType())) { - boolean filter = false; + var notifications = cacheManager.getDeviceObjects(event.getDeviceId(), Notification.class).stream() + .filter(notification -> notification.getType().equals(event.getType())) + .filter(notification -> { if (event.getType().equals(Event.TYPE_ALARM)) { String alarmsAttribute = notification.getString("alarms"); - if (alarmsAttribute == null) { - filter = true; - } else { - List alarms = Arrays.asList(alarmsAttribute.split(",")); - filter = !alarms.contains(event.getString(Position.KEY_ALARM)); + if (alarmsAttribute != null) { + return Arrays.asList(alarmsAttribute.split(",")) + .contains(event.getString(Position.KEY_ALARM)); } + return false; } - if (!filter) { - notificators.addAll(notification.getNotificatorsTypes()); - } - } - } + return true; + }) + .filter(notification -> { + long calendarId = notification.getCalendarId(); + Calendar calendar = calendarId != 0 ? cacheManager.getObject(Calendar.class, calendarId) : null; + return calendar == null || calendar.checkMoment(event.getEventTime()); + }) + .collect(Collectors.toUnmodifiableList()); + if (!notifications.isEmpty()) { if (position != null && position.getAddress() == null && geocodeOnRequest && geocoder != null) { position.setAddress(geocoder.getAddress(position.getLatitude(), position.getLongitude(), null)); } - User user = Context.getUsersManager().getById(userId); - new Thread(() -> { - for (String notificator : notificators) { - try { - notificatorManager.getNotificator(notificator).send(user, event, position); - } catch (MessageException | InterruptedException exception) { - LOGGER.warn("Notification failed", exception); - } - } - }).start(); + notifications.forEach(notification -> { + cacheManager.getNotificationUsers(notification.getId()).forEach(user -> { + new Thread(() -> { + for (String notificator : notification.getNotificatorsTypes()) { + try { + notificatorManager.getNotificator(notificator).send(user, event, position); + } catch (MessageException | InterruptedException exception) { + LOGGER.warn("Notification failed", exception); + } + } + }).start(); + }); + }); } + if (eventForwarder != null) { - eventForwarder.forwardEvent(event, position, usersToForward); + eventForwarder.forwardEvent(event, position); } } @@ -139,19 +122,4 @@ public class NotificationManager extends ExtendedObjectManager { updateEvent(event.getKey(), event.getValue()); } } - - public Set getAllNotificationTypes() { - Set types = new HashSet<>(); - Field[] fields = Event.class.getDeclaredFields(); - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { - try { - types.add(new Typed(field.get(null).toString())); - } catch (IllegalArgumentException | IllegalAccessException error) { - LOGGER.warn("Get event types error", error); - } - } - } - return types; - } } diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 3c74c0049..f34810439 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -22,7 +22,6 @@ import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.ManagedUser; -import org.traccar.model.Notification; import org.traccar.model.Permission; import org.traccar.model.Server; import org.traccar.model.User; @@ -237,31 +236,11 @@ public class PermissionsManager { } } - public void checkDeviceLimit(long userId) throws SecurityException { - int deviceLimit = getUser(userId).getDeviceLimit(); - if (deviceLimit != -1) { - int deviceCount; - if (getUserManager(userId)) { - deviceCount = Context.getDeviceManager().getAllManagedItems(userId).size(); - } else { - deviceCount = Context.getDeviceManager().getAllUserItems(userId).size(); - } - if (deviceCount >= deviceLimit) { - throw new SecurityException("User device limit reached"); - } - } - } - public boolean getUserReadonly(long userId) { User user = getUser(userId); return user != null && user.getReadonly(); } - public boolean getUserLimitCommands(long userId) { - User user = getUser(userId); - return user != null && user.getLimitCommands(); - } - public void checkReadonly(long userId) throws SecurityException { if (!getUserAdmin(userId) && (server.getReadonly() || getUserReadonly(userId))) { throw new SecurityException("Account is readonly"); @@ -313,18 +292,6 @@ public class PermissionsManager { } } - public void checkGroup(long userId, long groupId) throws SecurityException { - if (!getGroupPermissions(userId).contains(groupId) && !getUserAdmin(userId)) { - checkManager(userId); - for (long managedUserId : usersManager.getUserItems(userId)) { - if (getGroupPermissions(managedUserId).contains(groupId)) { - return; - } - } - throw new SecurityException("Group access denied"); - } - } - public void checkDevice(long userId, long deviceId) throws SecurityException { if (!Context.getDeviceManager().getUserItems(userId).contains(deviceId) && !getUserAdmin(userId)) { checkManager(userId); @@ -354,31 +321,13 @@ public class PermissionsManager { } } - public void refreshAllUsersPermissions() { - if (Context.getNotificationManager() != null) { - Context.getNotificationManager().refreshUserItems(); - } - } - - public void refreshAllExtendedPermissions() { - } - public void refreshPermissions(Permission permission) { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) || permission.getPropertyClass().equals(Group.class)) { refreshDeviceAndGroupPermissions(); - refreshAllExtendedPermissions(); } else if (permission.getPropertyClass().equals(ManagedUser.class)) { usersManager.refreshUserItems(); - } else if (permission.getPropertyClass().equals(Notification.class) - && Context.getNotificationManager() != null) { - Context.getNotificationManager().refreshUserItems(); - } - } else if (permission.getOwnerClass().equals(Device.class) || permission.getOwnerClass().equals(Group.class)) { - if (permission.getPropertyClass().equals(Notification.class) - && Context.getNotificationManager() != null) { - Context.getNotificationManager().refreshExtendedPermissions(); } } } diff --git a/src/main/java/org/traccar/handler/events/BaseEventHandler.java b/src/main/java/org/traccar/handler/events/BaseEventHandler.java index 41f677f6c..f7199f6dc 100644 --- a/src/main/java/org/traccar/handler/events/BaseEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BaseEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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,17 +18,26 @@ package org.traccar.handler.events; import java.util.Map; import org.traccar.BaseDataHandler; -import org.traccar.Context; +import org.traccar.database.NotificationManager; import org.traccar.model.Event; import org.traccar.model.Position; +import javax.inject.Inject; + public abstract class BaseEventHandler extends BaseDataHandler { + private NotificationManager notificationManager; + + @Inject + public void setNotificationManager(NotificationManager notificationManager) { + this.notificationManager = notificationManager; + } + @Override protected Position handlePosition(Position position) { Map events = analyzePosition(position); - if (events != null && Context.getNotificationManager() != null) { - Context.getNotificationManager().updateEvents(events); + if (events != null) { + notificationManager.updateEvents(events); } return position; } diff --git a/src/main/java/org/traccar/notification/EventForwarder.java b/src/main/java/org/traccar/notification/EventForwarder.java index 5afff1b7b..279d5e678 100644 --- a/src/main/java/org/traccar/notification/EventForwarder.java +++ b/src/main/java/org/traccar/notification/EventForwarder.java @@ -19,7 +19,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.UsersManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -33,7 +32,6 @@ import javax.ws.rs.client.Invocation; import javax.ws.rs.client.InvocationCallback; import java.util.HashMap; import java.util.Map; -import java.util.Set; public class EventForwarder { @@ -44,12 +42,10 @@ public class EventForwarder { private final Client client; private final CacheManager cacheManager; - private final UsersManager usersManager; - public EventForwarder(Config config, Client client, CacheManager cacheManager, UsersManager usersManager) { + public EventForwarder(Config config, Client client, CacheManager cacheManager) { this.client = client; this.cacheManager = cacheManager; - this.usersManager = usersManager; url = config.getString(Keys.EVENT_FORWARD_URL); header = config.getString(Keys.EVENT_FORWARD_HEADERS); } @@ -59,9 +55,8 @@ public class EventForwarder { private static final String KEY_GEOFENCE = "geofence"; private static final String KEY_DEVICE = "device"; private static final String KEY_MAINTENANCE = "maintenance"; - private static final String KEY_USERS = "users"; - public final void forwardEvent(Event event, Position position, Set users) { + public final void forwardEvent(Event event, Position position) { Invocation.Builder requestBuilder = client.target(url).request(); @@ -74,7 +69,7 @@ public class EventForwarder { LOGGER.debug("Event forwarding initiated"); requestBuilder.async().post( - Entity.json(preparePayload(event, position, users)), new InvocationCallback() { + Entity.json(preparePayload(event, position)), new InvocationCallback() { @Override public void completed(Object o) { LOGGER.debug("Event forwarding succeeded"); @@ -87,7 +82,7 @@ public class EventForwarder { }); } - protected Map preparePayload(Event event, Position position, Set users) { + protected Map preparePayload(Event event, Position position) { Map data = new HashMap<>(); data.put(KEY_EVENT, event); if (position != null) { @@ -109,7 +104,6 @@ public class EventForwarder { data.put(KEY_MAINTENANCE, maintenance); } } - data.put(KEY_USERS, usersManager.getItems(users)); return data; } diff --git a/src/main/java/org/traccar/notification/NotificatorManager.java b/src/main/java/org/traccar/notification/NotificatorManager.java index d6ebb2c4a..1d9f4f423 100644 --- a/src/main/java/org/traccar/notification/NotificatorManager.java +++ b/src/main/java/org/traccar/notification/NotificatorManager.java @@ -16,29 +16,29 @@ */ package org.traccar.notification; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - +import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Typed; +import org.traccar.notificators.Notificator; import org.traccar.notificators.NotificatorFirebase; import org.traccar.notificators.NotificatorMail; import org.traccar.notificators.NotificatorNull; -import org.traccar.notificators.Notificator; +import org.traccar.notificators.NotificatorPushover; import org.traccar.notificators.NotificatorSms; +import org.traccar.notificators.NotificatorTelegram; import org.traccar.notificators.NotificatorTraccar; import org.traccar.notificators.NotificatorWeb; -import org.traccar.notificators.NotificatorTelegram; -import org.traccar.notificators.NotificatorPushover; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; @Singleton public class NotificatorManager { @@ -54,36 +54,33 @@ public class NotificatorManager { "telegram", NotificatorTelegram.class, "pushover", NotificatorPushover.class); - private final Map notificators = new HashMap<>(); + private final Injector injector; + + private final Set types = new HashSet<>(); @Inject - public NotificatorManager(Config config) { + public NotificatorManager(Injector injector, Config config) { + this.injector = injector; String types = config.getString(Keys.NOTIFICATOR_TYPES); if (types != null) { - for (String type : types.split(",")) { - var notificatorClass = NOTIFICATORS_ALL.get(type); - if (notificatorClass != null) { - notificators.put(type, Main.getInjector().getInstance(notificatorClass)); - } - } + this.types.addAll(Arrays.asList(types.split(","))); } } public Notificator getNotificator(String type) { - final Notificator notificator = notificators.get(type); - if (notificator == null) { - LOGGER.warn("No notificator configured for type : " + type); - return new NotificatorNull(); + var clazz = NOTIFICATORS_ALL.get(type); + if (clazz != null) { + var notificator = injector.getInstance(clazz); + if (notificator != null) { + return notificator; + } } - return notificator; + LOGGER.warn("Failed to get notificator {}", type); + return new NotificatorNull(); } public Set getAllNotificatorTypes() { - Set result = new HashSet<>(); - for (String notificator : notificators.keySet()) { - result.add(new Typed(notificator)); - } - return result; + return types.stream().map(Typed::new).collect(Collectors.toUnmodifiableSet()); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index ab3c36734..dc714379b 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -25,6 +25,7 @@ import org.traccar.Main; import org.traccar.Protocol; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.NotificationManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; import org.traccar.model.Device; @@ -63,6 +64,7 @@ public class ConnectionManager { private final Config config; private final CacheManager cacheManager; private final Storage storage; + private final NotificationManager notificationManager; private final Timer timer; private final Map> listeners = new ConcurrentHashMap<>(); @@ -70,10 +72,12 @@ public class ConnectionManager { @Inject public ConnectionManager( - Config config, CacheManager cacheManager, Storage storage, Timer timer) { + Config config, CacheManager cacheManager, Storage storage, + NotificationManager notificationManager, Timer timer) { this.config = config; this.cacheManager = cacheManager; this.storage = storage; + this.notificationManager = notificationManager; this.timer = timer; deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT) * 1000; updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); @@ -163,7 +167,6 @@ public class ConnectionManager { if (defaultGroupId != 0) { Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - Context.getPermissionsManager().refreshAllExtendedPermissions(); } return device; @@ -236,7 +239,7 @@ public class ConnectionManager { break; } events.put(new Event(eventType, deviceId), null); - Context.getNotificationManager().updateEvents(events); + notificationManager.updateEvents(events); } Timeout timeout = timeouts.remove(deviceId); -- cgit v1.2.3 From 63ecf80c11ec9bce19df18fc24ad863a9c2cb212 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 15 Jun 2022 09:55:50 -0700 Subject: Remove users manager --- schema/changelog-5.1.xml | 12 +++ src/main/java/org/traccar/Context.java | 13 +-- src/main/java/org/traccar/MainModule.java | 9 +- .../java/org/traccar/api/BaseObjectResource.java | 17 ++-- .../org/traccar/api/resource/DeviceResource.java | 16 ++-- .../org/traccar/api/resource/PasswordResource.java | 43 +++++----- .../org/traccar/api/resource/SessionResource.java | 6 +- .../org/traccar/api/resource/UserResource.java | 77 ++++++++++------- .../traccar/api/security/PermissionsService.java | 33 +++++++- .../java/org/traccar/database/DataManager.java | 3 +- .../java/org/traccar/database/DeviceManager.java | 16 ---- .../org/traccar/database/PermissionsManager.java | 98 ++++----------------- .../org/traccar/database/SimpleObjectManager.java | 70 --------------- .../java/org/traccar/database/UsersManager.java | 99 ---------------------- 14 files changed, 153 insertions(+), 359 deletions(-) delete mode 100644 src/main/java/org/traccar/database/UsersManager.java diff --git a/schema/changelog-5.1.xml b/schema/changelog-5.1.xml index e68325625..e972813f6 100644 --- a/schema/changelog-5.1.xml +++ b/schema/changelog-5.1.xml @@ -16,6 +16,18 @@ + + + + + + + + + + + + diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 51c420390..5eaa1e15c 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -23,12 +23,10 @@ import org.traccar.database.DeviceManager; import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; import org.traccar.database.PermissionsManager; -import org.traccar.database.UsersManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.model.User; import org.traccar.session.ConnectionManager; public final class Context { @@ -54,12 +52,6 @@ public final class Context { return dataManager; } - private static UsersManager usersManager; - - public static UsersManager getUsersManager() { - return usersManager; - } - private static GroupsManager groupsManager; public static GroupsManager getGroupsManager() { @@ -94,7 +86,6 @@ public final class Context { } if (dataManager != null) { - usersManager = new UsersManager(dataManager); groupsManager = new GroupsManager(dataManager); deviceManager = new DeviceManager( config, dataManager, Main.getInjector().getInstance(ConnectionManager.class)); @@ -102,7 +93,7 @@ public final class Context { identityManager = deviceManager; - permissionsManager = new PermissionsManager(dataManager, usersManager); + permissionsManager = new PermissionsManager(dataManager, dataManager.getStorage()); } @@ -111,8 +102,6 @@ public final class Context { return (BaseObjectManager) deviceManager; } else if (clazz.equals(Group.class)) { return (BaseObjectManager) groupsManager; - } else if (clazz.equals(User.class)) { - return (BaseObjectManager) usersManager; } return null; } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index dd496e5a4..dd7e375d3 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -31,7 +31,6 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; -import org.traccar.database.UsersManager; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; import org.traccar.database.DataManager; @@ -118,11 +117,6 @@ public class MainModule extends AbstractModule { return Context.getDataManager(); } - @Provides - public static UsersManager provideUsersManager() { - return Context.getUsersManager(); - } - @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); @@ -292,8 +286,7 @@ public class MainModule extends AbstractModule { } @Provides - public static EventForwarder provideEventForwarder( - Config config, Client client, CacheManager cacheManager, UsersManager usersManager) { + public static EventForwarder provideEventForwarder(Config config, Client client, CacheManager cacheManager) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { return new EventForwarder(config, client, cacheManager); } diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index aa777f3f6..f8545a5d7 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -19,7 +19,6 @@ package org.traccar.api; import org.traccar.Context; import org.traccar.database.BaseObjectManager; import org.traccar.database.ExtendedObjectManager; -import org.traccar.database.SimpleObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -82,9 +81,7 @@ public abstract class BaseObjectResource extends BaseResour cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); - if (manager instanceof SimpleObjectManager) { - ((SimpleObjectManager) manager).refreshUserItems(); - } else if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { + if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); } return Response.ok(entity).build(); @@ -95,6 +92,11 @@ public abstract class BaseObjectResource extends BaseResour public Response update(T entity) throws StorageException { permissionsService.checkEdit(getUserId(), entity, false); permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); + if (entity instanceof User) { + User before = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); + permissionsService.checkUserUpdate(getUserId(), before, (User) entity); + } BaseObjectManager manager = Context.getManager(baseClass); if (manager != null) { @@ -123,11 +125,8 @@ public abstract class BaseObjectResource extends BaseResour BaseObjectManager manager = Context.getManager(baseClass); if (manager != null) { manager.removeItem(id); - if (manager instanceof SimpleObjectManager) { - ((SimpleObjectManager) manager).refreshUserItems(); - if (manager instanceof ExtendedObjectManager) { - ((ExtendedObjectManager) manager).refreshExtendedPermissions(); - } + if (manager instanceof ExtendedObjectManager) { + ((ExtendedObjectManager) manager).refreshExtendedPermissions(); } } else { storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 309308e75..cd5ebf0c5 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -49,7 +49,7 @@ public class DeviceResource extends BaseObjectResource { public Collection get( @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("uniqueId") List uniqueIds, - @QueryParam("id") List deviceIds) { + @QueryParam("id") List deviceIds) throws StorageException { DeviceManager deviceManager = Context.getDeviceManager(); Set result; if (all) { @@ -57,13 +57,13 @@ public class DeviceResource extends BaseObjectResource { result = deviceManager.getAllItems(); } else { Context.getPermissionsManager().checkManager(getUserId()); - result = deviceManager.getManagedItems(getUserId()); + result = deviceManager.getUserItems(getUserId()); } } else if (uniqueIds.isEmpty() && deviceIds.isEmpty()) { if (userId == 0) { userId = getUserId(); } - Context.getPermissionsManager().checkUser(getUserId(), userId); + permissionsService.checkUser(getUserId(), userId); if (Context.getPermissionsManager().getUserAdmin(getUserId())) { result = deviceManager.getAllUserItems(userId); } else { @@ -73,11 +73,11 @@ public class DeviceResource extends BaseObjectResource { result = new HashSet<>(); for (String uniqueId : uniqueIds) { Device device = deviceManager.getByUniqueId(uniqueId); - Context.getPermissionsManager().checkDevice(getUserId(), device.getId()); + permissionsService.checkPermission(Device.class, getUserId(), device.getId()); result.add(device.getId()); } for (Long deviceId : deviceIds) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + permissionsService.checkPermission(Device.class, getUserId(), deviceId); result.add(deviceId); } } @@ -87,9 +87,9 @@ public class DeviceResource extends BaseObjectResource { @Path("{id}/accumulators") @PUT public Response updateAccumulators(DeviceAccumulators entity) throws StorageException { - if (!Context.getPermissionsManager().getUserAdmin(getUserId())) { - Context.getPermissionsManager().checkManager(getUserId()); - Context.getPermissionsManager().checkPermission(Device.class, getUserId(), entity.getDeviceId()); + if (permissionsService.notAdmin(getUserId())) { + permissionsService.checkManager(getUserId()); + permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); } Context.getDeviceManager().resetDeviceAccumulators(entity); LogAction.resetDeviceAccumulators(getUserId(), entity.getDeviceId()); diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index c7244f41c..643471797 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -15,12 +15,14 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.database.MailManager; import org.traccar.model.User; import org.traccar.notification.TextTemplateFormatter; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; import javax.inject.Inject; @@ -51,18 +53,17 @@ public class PasswordResource extends BaseResource { @PermitAll @POST public Response reset(@FormParam("email") String email) throws StorageException, MessagingException { - for (long userId : Context.getUsersManager().getAllItems()) { - User user = Context.getUsersManager().getById(userId); - if (email.equals(user.getEmail())) { - String token = UUID.randomUUID().toString().replaceAll("-", ""); - user.set(PASSWORD_RESET_TOKEN, token); - Context.getUsersManager().updateItem(user); - var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); - velocityContext.put("token", token); - var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); - mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); - break; - } + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("email", "email", email))); + if (user != null) { + String token = UUID.randomUUID().toString().replaceAll("-", ""); + user.set(PASSWORD_RESET_TOKEN, token); + storage.updateObject(user, new Request(new Columns.Exclude("id"), new Condition.Equals("id", "id"))); + + var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); + velocityContext.put("token", token); + var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); + mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } return Response.ok().build(); } @@ -72,14 +73,14 @@ public class PasswordResource extends BaseResource { @POST public Response update( @FormParam("token") String token, @FormParam("password") String password) throws StorageException { - for (long userId : Context.getUsersManager().getAllItems()) { - User user = Context.getUsersManager().getById(userId); - if (token.equals(user.getString(PASSWORD_RESET_TOKEN))) { - user.getAttributes().remove(PASSWORD_RESET_TOKEN); - user.setPassword(password); - Context.getUsersManager().updateItem(user); - return Response.ok().build(); - } + User user = storage.getObjects(User.class, new Request(new Columns.All())).stream() + .filter(it -> token.equals(it.getString(PASSWORD_RESET_TOKEN))) + .findFirst().orElse(null); + if (user != null) { + user.getAttributes().remove(PASSWORD_RESET_TOKEN); + user.setPassword(password); + storage.updateObject(user, new Request(new Columns.Exclude("id"), new Condition.Equals("id", "id"))); + return Response.ok().build(); } return Response.status(Response.Status.NOT_FOUND).build(); } diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 1ccba1270..a0bf0cba5 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -22,6 +22,9 @@ import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; import org.traccar.model.User; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; import javax.servlet.http.Cookie; @@ -59,7 +62,8 @@ public class SessionResource extends BaseResource { public User get(@QueryParam("token") String token) throws StorageException, UnsupportedEncodingException { if (token != null) { - User user = Context.getUsersManager().getUserByToken(token); + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("token", "token", token))); if (user != null) { Context.getPermissionsManager().checkUserEnabled(user.getId()); request.getSession().setAttribute(USER_ID_KEY, user.getId()); diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 84f41ca1a..20fce9e32 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,17 +15,20 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseObjectResource; +import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.UsersManager; import org.traccar.helper.LogAction; import org.traccar.model.ManagedUser; import org.traccar.model.Permission; import org.traccar.model.User; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -34,63 +37,77 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.sql.SQLException; import java.util.Collection; import java.util.Date; -import java.util.Set; @Path("users") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class UserResource extends BaseObjectResource { + @Inject + private Config config; + public UserResource() { super(User.class); } @GET - public Collection get(@QueryParam("userId") long userId) throws SQLException { - UsersManager usersManager = Context.getUsersManager(); - Set result; - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - if (userId != 0) { - result = usersManager.getUserItems(userId); - } else { - result = usersManager.getAllItems(); - } - } else if (Context.getPermissionsManager().getUserManager(getUserId())) { - result = usersManager.getManagedItems(getUserId()); + public Collection get(@QueryParam("userId") long userId) throws StorageException { + permissionsService.checkUser(getUserId(), userId); + if (userId > 0) { + return storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups())); + } else if (permissionsService.notAdmin(getUserId())) { + return storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())); } else { - throw new SecurityException("Admin or manager access required"); + return storage.getObjects(baseClass, new Request(new Columns.All())); } - return usersManager.getItems(result); } @Override @PermitAll @POST public Response add(User entity) throws StorageException { - if (!Context.getPermissionsManager().getUserAdmin(getUserId())) { - Context.getPermissionsManager().checkUserUpdate(getUserId(), new User(), entity); - if (Context.getPermissionsManager().getUserManager(getUserId())) { - Context.getPermissionsManager().checkUserLimit(getUserId()); + User currentUser = permissionsService.getUser(getUserId()); + if (permissionsService.notAdmin(getUserId())) { + permissionsService.checkUserUpdate(getUserId(), new User(), entity); + if (currentUser != null && currentUser.getUserLimit() != 0) { + int userLimit = currentUser.getUserLimit(); + if (userLimit > 0) { + int userCount = storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, getUserId(), ManagedUser.class).excludeGroups())) + .size(); + if (userCount >= userLimit) { + throw new SecurityException("Manager user limit reached"); + } + } } else { - Context.getPermissionsManager().checkRegistration(getUserId()); - entity.setDeviceLimit(Context.getConfig().getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT)); - int expirationDays = Context.getConfig().getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS); + if (!permissionsService.getServer().getRegistration()) { + throw new SecurityException("Registration disabled"); + } + entity.setDeviceLimit(config.getInteger(Keys.USERS_DEFAULT_DEVICE_LIMIT)); + int expirationDays = config.getInteger(Keys.USERS_DEFAULT_EXPIRATION_DAYS); if (expirationDays > 0) { - entity.setExpirationTime( - new Date(System.currentTimeMillis() + (long) expirationDays * 24 * 3600 * 1000)); + entity.setExpirationTime(new Date(System.currentTimeMillis() + expirationDays * 86400000L)); } } } - Context.getUsersManager().addItem(entity); + + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); + storage.updateObject(entity, new Request( + new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + LogAction.create(getUserId(), entity); - if (Context.getPermissionsManager().getUserManager(getUserId())) { + + if (currentUser != null && currentUser.getUserLimit() != 0) { storage.addPermission(new Permission(User.class, getUserId(), ManagedUser.class, entity.getId())); LogAction.link(getUserId(), User.class, getUserId(), ManagedUser.class, entity.getId()); } - Context.getUsersManager().refreshUserItems(); return Response.ok(entity).build(); } diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index c70414b2a..f39ded2b7 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -57,7 +57,7 @@ public class PermissionsService { } public User getUser(long userId) throws StorageException { - if (user == null) { + if (user == null && userId > 0) { user = storage.getObject( User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); } @@ -74,6 +74,12 @@ public class PermissionsService { } } + public void checkManager(long userId) throws StorageException, SecurityException { + if (!getUser(userId).getAdministrator() && getUser(userId).getUserLimit() == 0) { + throw new SecurityException("Manager access required"); + } + } + public interface CheckRestrictionCallback { boolean denied(UserRestrictions userRestrictions); } @@ -137,6 +143,31 @@ public class PermissionsService { } } + public void checkUserUpdate(long userId, User before, User after) throws StorageException, SecurityException { + if (before.getAdministrator() != after.getAdministrator() + || before.getDeviceLimit() != after.getDeviceLimit() + || before.getUserLimit() != after.getUserLimit()) { + checkAdmin(userId); + } + User user = getUser(userId); + if (user != null && user.getExpirationTime() != null + && (after.getExpirationTime() == null + || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) { + checkAdmin(userId); + } + if (before.getReadonly() != after.getReadonly() + || before.getDeviceReadonly() != after.getDeviceReadonly() + || before.getDisabled() != after.getDisabled() + || before.getLimitCommands() != after.getLimitCommands() + || before.getDisableReports() != after.getDisableReports()) { + if (userId == after.getId()) { + checkAdmin(userId); + } else { + checkUser(userId, after.getId()); + } + } + } + public void checkPermission( Class clazz, long userId, long objectId) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator() && !(clazz.equals(User.class) && userId == objectId)) { diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index fd45a0321..6921634dd 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -25,7 +25,6 @@ import liquibase.database.DatabaseFactory; import liquibase.exception.LiquibaseException; import liquibase.resource.FileSystemResourceAccessor; import liquibase.resource.ResourceAccessor; -import org.traccar.Context; import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -155,7 +154,7 @@ public class DataManager { } else { if (ldapProvider != null && ldapProvider.login(email, password)) { user = ldapProvider.getUser(email); - Context.getUsersManager().addItem(user); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); return user; } } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index e1d6ad1dd..9ba486988 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -177,22 +177,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - public Set getAllManagedItems(long userId) { - Set result = new HashSet<>(getAllUserItems(userId)); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getAllUserItems(managedUserId)); - } - return result; - } - - public Set getManagedItems(long userId) { - Set result = new HashSet<>(getUserItems(userId)); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getUserItems(managedUserId)); - } - return result; - } - private void addByUniqueId(Device device) { try { writeLock(); diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index f34810439..833480eea 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -18,14 +18,17 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.model.BaseModel; +import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; -import org.traccar.model.ManagedUser; import org.traccar.model.Permission; import org.traccar.model.Server; import org.traccar.model.User; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import java.util.HashMap; import java.util.HashSet; @@ -39,7 +42,7 @@ public class PermissionsManager { private static final Logger LOGGER = LoggerFactory.getLogger(PermissionsManager.class); private final DataManager dataManager; - private final UsersManager usersManager; + private final Storage storage; private volatile Server server; @@ -50,9 +53,9 @@ public class PermissionsManager { private final Map> deviceUsers = new HashMap<>(); private final Map> groupDevices = new HashMap<>(); - public PermissionsManager(DataManager dataManager, UsersManager usersManager) { + public PermissionsManager(DataManager dataManager, Storage storage) { this.dataManager = dataManager; - this.usersManager = usersManager; + this.storage = storage; refreshServer(); refreshDeviceAndGroupPermissions(); } @@ -74,11 +77,11 @@ public class PermissionsManager { } public User getUser(long userId) { - readLock(); try { - return usersManager.getById(userId); - } finally { - readUnlock(); + return storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", userId))); + } catch (StorageException e) { + throw new RuntimeException(e); } } @@ -222,20 +225,6 @@ public class PermissionsManager { } } - public void checkManager(long userId, long managedUserId) throws SecurityException { - checkManager(userId); - if (!usersManager.getUserItems(userId).contains(managedUserId)) { - throw new SecurityException("User access denied"); - } - } - - public void checkUserLimit(long userId) throws SecurityException { - int userLimit = getUser(userId).getUserLimit(); - if (userLimit != -1 && usersManager.getUserItems(userId).size() >= userLimit) { - throw new SecurityException("Manager user limit reached"); - } - } - public boolean getUserReadonly(long userId) { User user = getUser(userId); return user != null && user.getReadonly(); @@ -260,64 +249,11 @@ public class PermissionsManager { } } - public void checkUserUpdate(long userId, User before, User after) throws SecurityException { - if (before.getAdministrator() != after.getAdministrator() - || before.getDeviceLimit() != after.getDeviceLimit() - || before.getUserLimit() != after.getUserLimit()) { - checkAdmin(userId); - } - User user = getUser(userId); - if (user != null && user.getExpirationTime() != null - && (after.getExpirationTime() == null - || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) { - checkAdmin(userId); - } - if (before.getReadonly() != after.getReadonly() - || before.getDeviceReadonly() != after.getDeviceReadonly() - || before.getDisabled() != after.getDisabled() - || before.getLimitCommands() != after.getLimitCommands() - || before.getDisableReports() != after.getDisableReports()) { - if (userId == after.getId()) { - checkAdmin(userId); - } - if (!getUserAdmin(userId)) { - checkManager(userId); - } - } - } - - public void checkUser(long userId, long managedUserId) throws SecurityException { - if (userId != managedUserId && !getUserAdmin(userId)) { - checkManager(userId, managedUserId); - } - } - public void checkDevice(long userId, long deviceId) throws SecurityException { - if (!Context.getDeviceManager().getUserItems(userId).contains(deviceId) && !getUserAdmin(userId)) { - checkManager(userId); - for (long managedUserId : usersManager.getUserItems(userId)) { - if (Context.getDeviceManager().getUserItems(managedUserId).contains(deviceId)) { - return; - } - } - throw new SecurityException("Device access denied"); - } - } - - public void checkRegistration(long userId) { - if (!server.getRegistration() && !getUserAdmin(userId)) { - throw new SecurityException("Registration disabled"); - } - } - - public void checkPermission(Class object, long userId, long objectId) - throws SecurityException { - SimpleObjectManager manager = null; - - if (object.equals(Device.class)) { - checkDevice(userId, objectId); - } else { - throw new IllegalArgumentException("Unknown object type"); + try { + new PermissionsService(storage).checkPermission(Device.class, userId, deviceId); + } catch (StorageException e) { + throw new RuntimeException(e); } } @@ -326,8 +262,6 @@ public class PermissionsManager { if (permission.getPropertyClass().equals(Device.class) || permission.getPropertyClass().equals(Group.class)) { refreshDeviceAndGroupPermissions(); - } else if (permission.getPropertyClass().equals(ManagedUser.class)) { - usersManager.refreshUserItems(); } } } diff --git a/src/main/java/org/traccar/database/SimpleObjectManager.java b/src/main/java/org/traccar/database/SimpleObjectManager.java index 74bbc054f..8bb22b8a8 100644 --- a/src/main/java/org/traccar/database/SimpleObjectManager.java +++ b/src/main/java/org/traccar/database/SimpleObjectManager.java @@ -16,82 +16,12 @@ */ package org.traccar.database; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.model.BaseModel; -import org.traccar.model.Permission; -import org.traccar.model.User; -import org.traccar.storage.StorageException; public abstract class SimpleObjectManager extends BaseObjectManager { - private static final Logger LOGGER = LoggerFactory.getLogger(SimpleObjectManager.class); - - private Map> userItems; - protected SimpleObjectManager(DataManager dataManager, Class baseClass) { super(dataManager, baseClass); } - public final Set getUserItems(long userId) { - try { - readLock(); - Set result = userItems.get(userId); - if (result != null) { - return new HashSet<>(result); - } else { - return new HashSet<>(); - } - } finally { - readUnlock(); - } - } - - public Set getManagedItems(long userId) { - Set result = getUserItems(userId); - for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { - result.addAll(getUserItems(managedUserId)); - } - return result; - } - - public final boolean checkItemPermission(long userId, long itemId) { - return getUserItems(userId).contains(itemId); - } - - @Override - public void refreshItems() { - super.refreshItems(); - refreshUserItems(); - } - - public final void refreshUserItems() { - if (getDataManager() != null) { - try { - writeLock(); - userItems = new ConcurrentHashMap<>(); - for (Permission permission : getDataManager().getPermissions(User.class, getBaseClass())) { - Set items = userItems.computeIfAbsent(permission.getOwnerId(), key -> new HashSet<>()); - items.add(permission.getPropertyId()); - } - } catch (StorageException | ClassNotFoundException error) { - LOGGER.warn("Error getting permissions", error); - } finally { - writeUnlock(); - } - } - } - - @Override - public void removeItem(long itemId) throws StorageException { - super.removeItem(itemId); - refreshUserItems(); - } - } diff --git a/src/main/java/org/traccar/database/UsersManager.java b/src/main/java/org/traccar/database/UsersManager.java deleted file mode 100644 index a54226cfe..000000000 --- a/src/main/java/org/traccar/database/UsersManager.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.database; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.traccar.model.User; -import org.traccar.storage.StorageException; - -public class UsersManager extends SimpleObjectManager { - - private Map usersTokens; - - public UsersManager(DataManager dataManager) { - super(dataManager, User.class); - if (usersTokens == null) { - usersTokens = new ConcurrentHashMap<>(); - } - } - - private void putToken(User user) { - if (usersTokens == null) { - usersTokens = new ConcurrentHashMap<>(); - } - if (user.getToken() != null) { - usersTokens.put(user.getToken(), user); - } - } - - @Override - protected void addNewItem(User user) { - super.addNewItem(user); - putToken(user); - } - - @Override - protected void updateCachedItem(User user) { - User cachedUser = getById(user.getId()); - super.updateCachedItem(user); - putToken(user); - if (cachedUser.getToken() != null && !cachedUser.getToken().equals(user.getToken())) { - usersTokens.remove(cachedUser.getToken()); - } - } - - @Override - public void addItem(User user) throws StorageException { - super.addItem(user); - getDataManager().updateUserPassword(user); - } - - @Override - public void updateItem(User user) throws StorageException { - if (user.getHashedPassword() != null) { - getDataManager().updateUserPassword(user); - } - super.updateItem(user); - } - - @Override - protected void removeCachedItem(long userId) { - User cachedUser = getById(userId); - if (cachedUser != null) { - String userToken = cachedUser.getToken(); - super.removeCachedItem(userId); - if (userToken != null) { - usersTokens.remove(userToken); - } - } - } - - @Override - public Set getManagedItems(long userId) { - Set result = getUserItems(userId); - result.add(userId); - return result; - } - - public User getUserByToken(String token) { - return usersTokens.get(token); - } - -} -- cgit v1.2.3 From ca884b765f3f7a642c435be886dbec40f9d1f661 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 15 Jun 2022 19:08:58 -0700 Subject: Convert some config usages --- src/main/java/org/traccar/BasePipelineFactory.java | 7 ++++--- src/main/java/org/traccar/BaseProtocolDecoder.java | 24 +++------------------- .../java/org/traccar/ExtendedObjectDecoder.java | 22 +++++++++++++++++++- src/main/java/org/traccar/MainEventHandler.java | 8 ++++---- src/main/java/org/traccar/ServerManager.java | 6 ++++-- src/main/java/org/traccar/TrackerClient.java | 15 +++++++------- src/main/java/org/traccar/TrackerServer.java | 12 ++++++----- .../traccar/api/resource/AttributeResource.java | 7 ++++++- .../java/org/traccar/handler/GeocoderHandler.java | 3 +-- src/main/java/org/traccar/handler/TimeHandler.java | 3 +-- 10 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 1f383f211..3eb7011a1 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -22,6 +22,7 @@ import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOutboundHandler; import io.netty.channel.ChannelPipeline; import io.netty.handler.timeout.IdleStateHandler; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.handler.ComputedAttributesHandler; import org.traccar.handler.CopyAttributesHandler; @@ -58,12 +59,12 @@ public abstract class BasePipelineFactory extends ChannelInitializer { private final String protocol; private int timeout; - public BasePipelineFactory(TrackerConnector connector, String protocol) { + public BasePipelineFactory(TrackerConnector connector, Config config, String protocol) { this.connector = connector; this.protocol = protocol; - timeout = Context.getConfig().getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); + timeout = config.getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); if (timeout == 0) { - timeout = Context.getConfig().getInteger(Keys.SERVER_TIMEOUT); + timeout = config.getInteger(Keys.SERVER_TIMEOUT); } } diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 5b3f129de..cbcb429b3 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; -import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.CommandsManager; import org.traccar.database.IdentityManager; @@ -46,7 +45,6 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private final Protocol protocol; - private Config config; private IdentityManager identityManager; private ConnectionManager connectionManager; private StatisticsManager statisticsManager; @@ -57,22 +55,6 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { this.protocol = protocol; } - /** - * Method called when config is initialized. - */ - protected void init() { - } - - public Config getConfig() { - return config; - } - - @Inject - public void setConfig(Config config) { - this.config = config; - init(); - } - public IdentityManager getIdentityManager() { return identityManager; } @@ -115,7 +97,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } public String getServer(Channel channel, char delimiter) { - String server = config.getString(Keys.PROTOCOL_SERVER.withPrefix(getProtocolName())); + String server = getConfig().getString(Keys.PROTOCOL_SERVER.withPrefix(getProtocolName())); if (server == null && channel != null) { InetSocketAddress address = (InetSocketAddress) channel.localAddress(); server = address.getAddress().getHostAddress() + ":" + address.getPort(); @@ -124,7 +106,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } protected double convertSpeed(double value, String defaultUnits) { - switch (config.getString(getProtocolName() + ".speed", defaultUnits)) { + switch (getConfig().getString(getProtocolName() + ".speed", defaultUnits)) { case "kmh": return UnitsConverter.knotsFromKph(value); case "mps": @@ -222,7 +204,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { @Override protected Object handleEmptyMessage(Channel channel, SocketAddress remoteAddress, Object msg) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (config.getBoolean(Keys.DATABASE_SAVE_EMPTY) && deviceSession != null) { + if (getConfig().getBoolean(Keys.DATABASE_SAVE_EMPTY) && deviceSession != null) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); diff --git a/src/main/java/org/traccar/ExtendedObjectDecoder.java b/src/main/java/org/traccar/ExtendedObjectDecoder.java index 46720da52..f79a36c85 100644 --- a/src/main/java/org/traccar/ExtendedObjectDecoder.java +++ b/src/main/java/org/traccar/ExtendedObjectDecoder.java @@ -21,18 +21,38 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.ReferenceCountUtil; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.DataConverter; import org.traccar.model.Position; +import javax.inject.Inject; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Collection; public abstract class ExtendedObjectDecoder extends ChannelInboundHandlerAdapter { + private Config config; + + public Config getConfig() { + return config; + } + + @Inject + public void setConfig(Config config) { + this.config = config; + init(); + } + + /** + * Method called when config is initialized. + */ + protected void init() { + } + private void saveOriginal(Object decodedMessage, Object originalMessage) { - if (Context.getConfig().getBoolean(Keys.DATABASE_SAVE_ORIGINAL) && decodedMessage instanceof Position) { + if (getConfig().getBoolean(Keys.DATABASE_SAVE_ORIGINAL) && decodedMessage instanceof Position) { Position position = (Position) decodedMessage; if (originalMessage instanceof ByteBuf) { ByteBuf buf = (ByteBuf) originalMessage; diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index d4a0fae6c..7fff2e13f 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -23,6 +23,7 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; @@ -48,14 +49,13 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final ConnectionManager connectionManager; @Inject - public MainEventHandler(ConnectionManager connectionManager) { + public MainEventHandler(Config config, ConnectionManager connectionManager) { this.connectionManager = connectionManager; - String connectionlessProtocolList = Context.getConfig().getString(Keys.STATUS_IGNORE_OFFLINE); + String connectionlessProtocolList = config.getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split("[, ]"))); } - logAttributes.addAll(Arrays.asList( - Context.getConfig().getString(Keys.LOGGER_ATTRIBUTES).split("[, ]"))); + logAttributes.addAll(Arrays.asList(config.getString(Keys.LOGGER_ATTRIBUTES).split("[, ]"))); } @Override diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index f4f6e1ba4..ffb15d8ca 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -18,6 +18,7 @@ package org.traccar; import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.ClassScanner; @@ -41,9 +42,10 @@ public class ServerManager implements LifecycleObject { private final Map protocolList = new ConcurrentHashMap<>(); @Inject - public ServerManager(Injector injector) throws IOException, URISyntaxException, ReflectiveOperationException { + public ServerManager( + Injector injector, Config config) throws IOException, URISyntaxException, ReflectiveOperationException { for (Class protocolClass : ClassScanner.findSubclasses(BaseProtocol.class, "org.traccar.protocol")) { - if (Context.getConfig().hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { + if (config.hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { BaseProtocol protocol = (BaseProtocol) protocolClass.getDeclaredConstructor().newInstance(); injector.injectMembers(protocol); connectorList.addAll(protocol.getConnectorList()); diff --git a/src/main/java/org/traccar/TrackerClient.java b/src/main/java/org/traccar/TrackerClient.java index 12971849c..5a3c38212 100644 --- a/src/main/java/org/traccar/TrackerClient.java +++ b/src/main/java/org/traccar/TrackerClient.java @@ -54,14 +54,15 @@ public abstract class TrackerClient implements TrackerConnector { } public TrackerClient(String protocol) { + Config config = Context.getConfig(); - secure = Context.getConfig().getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); - interval = Context.getConfig().getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol)); - address = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); - port = Context.getConfig().getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol), secure ? 443 : 80); - devices = Context.getConfig().getString(Keys.PROTOCOL_DEVICES.withPrefix(protocol)).split("[, ]"); + secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); + interval = config.getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol)); + address = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); + port = config.getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol), secure ? 443 : 80); + devices = config.getString(Keys.PROTOCOL_DEVICES.withPrefix(protocol)).split("[, ]"); - BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, protocol) { + BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, config, protocol) { @Override protected void addTransportHandlers(PipelineBuilder pipeline) { try { @@ -78,7 +79,7 @@ public abstract class TrackerClient implements TrackerConnector { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { try { - TrackerClient.this.addProtocolHandlers(pipeline, Context.getConfig()); + TrackerClient.this.addProtocolHandlers(pipeline, config); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index b279d3479..dd83ca6b0 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -58,11 +58,13 @@ public abstract class TrackerServer implements TrackerConnector { public TrackerServer(boolean datagram, String protocol) { this.datagram = datagram; - secure = Context.getConfig().getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); - address = Context.getConfig().getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); - port = Context.getConfig().getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol)); + Config config = Context.getConfig(); - BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, protocol) { + secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); + address = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); + port = config.getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol)); + + BasePipelineFactory pipelineFactory = new BasePipelineFactory(this, config, protocol) { @Override protected void addTransportHandlers(PipelineBuilder pipeline) { try { @@ -77,7 +79,7 @@ public abstract class TrackerServer implements TrackerConnector { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { - TrackerServer.this.addProtocolHandlers(pipeline, Context.getConfig()); + TrackerServer.this.addProtocolHandlers(pipeline, config); } }; diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index ab7e43add..43d8a7ccd 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -16,6 +16,7 @@ */ package org.traccar.api.resource; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.POST; @@ -29,6 +30,7 @@ import javax.ws.rs.core.Response; import org.traccar.Context; import org.traccar.api.ExtendedObjectResource; +import org.traccar.config.Config; import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; @@ -43,6 +45,9 @@ import org.traccar.storage.query.Request; @Consumes(MediaType.APPLICATION_JSON) public class AttributeResource extends ExtendedObjectResource { + @Inject + private Config config; + public AttributeResource() { super(Attribute.class); } @@ -57,7 +62,7 @@ public class AttributeResource extends ExtendedObjectResource { new Columns.All(), new Condition.LatestPositions(deviceId))); - Object result = new ComputedAttributesHandler(Context.getConfig(), Context.getIdentityManager(), null) + Object result = new ComputedAttributesHandler(config, Context.getIdentityManager(), null) .computeAttribute(entity, position); if (result != null) { switch (entity.getType()) { diff --git a/src/main/java/org/traccar/handler/GeocoderHandler.java b/src/main/java/org/traccar/handler/GeocoderHandler.java index 614cf97d6..075bdf815 100644 --- a/src/main/java/org/traccar/handler/GeocoderHandler.java +++ b/src/main/java/org/traccar/handler/GeocoderHandler.java @@ -20,7 +20,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.IdentityManager; @@ -42,7 +41,7 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { Config config, Geocoder geocoder, IdentityManager identityManager) { this.geocoder = geocoder; this.identityManager = identityManager; - ignorePositions = Context.getConfig().getBoolean(Keys.GEOCODER_IGNORE_POSITIONS); + ignorePositions = config.getBoolean(Keys.GEOCODER_IGNORE_POSITIONS); processInvalidPositions = config.getBoolean(Keys.GEOCODER_PROCESS_INVALID_POSITIONS); geocoderReuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0); } diff --git a/src/main/java/org/traccar/handler/TimeHandler.java b/src/main/java/org/traccar/handler/TimeHandler.java index c7e5e6e5c..439c076c7 100644 --- a/src/main/java/org/traccar/handler/TimeHandler.java +++ b/src/main/java/org/traccar/handler/TimeHandler.java @@ -19,7 +19,6 @@ import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Position; @@ -44,7 +43,7 @@ public class TimeHandler extends ChannelInboundHandlerAdapter { } else { useServerTime = false; } - String protocolList = Context.getConfig().getString(Keys.TIME_PROTOCOLS); + String protocolList = config.getString(Keys.TIME_PROTOCOLS); if (protocolList != null) { protocols = new HashSet<>(Arrays.asList(protocolList.split("[, ]"))); } else { -- cgit v1.2.3 From 481a902538b951a420d00c32063e0984e4e922d6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 06:48:48 -0700 Subject: Inject data source --- src/main/java/org/traccar/Context.java | 6 +- src/main/java/org/traccar/Main.java | 3 +- src/main/java/org/traccar/MainModule.java | 12 ++- .../java/org/traccar/database/DataManager.java | 97 +------------------ .../java/org/traccar/storage/DatabaseModule.java | 103 +++++++++++++++++++++ src/main/java/org/traccar/web/WebServer.java | 22 +++-- 6 files changed, 130 insertions(+), 113 deletions(-) create mode 100644 src/main/java/org/traccar/storage/DatabaseModule.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 5eaa1e15c..00ab05d57 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -28,6 +28,7 @@ import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.session.ConnectionManager; +import org.traccar.storage.Storage; public final class Context { @@ -82,7 +83,7 @@ public final class Context { } if (config.hasKey(Keys.DATABASE_URL)) { - dataManager = new DataManager(config); + dataManager = new DataManager(config, Main.getInjector().getInstance(Storage.class)); } if (dataManager != null) { @@ -93,7 +94,8 @@ public final class Context { identityManager = deviceManager; - permissionsManager = new PermissionsManager(dataManager, dataManager.getStorage()); + permissionsManager = new PermissionsManager( + dataManager, Main.getInjector().getInstance(Storage.class)); } diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 412ac1f5e..72eeb5885 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; import org.traccar.schedule.ScheduleManager; +import org.traccar.storage.DatabaseModule; import org.traccar.web.WebServer; import java.io.File; @@ -114,7 +115,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule(), new ServletModule()); + injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new ServletModule()); Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index dd7e375d3..4e95b2be0 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,12 +30,10 @@ import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.LdapProvider; -import org.traccar.helper.SanitizerModule; -import org.traccar.notification.EventForwarder; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; +import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; @@ -64,17 +62,21 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.helper.SanitizerModule; +import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; +import org.traccar.storage.DatabaseStorage; import org.traccar.storage.Storage; import org.traccar.web.WebServer; import javax.annotation.Nullable; import javax.inject.Singleton; +import javax.sql.DataSource; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.ext.ContextResolver; @@ -108,8 +110,8 @@ public class MainModule extends AbstractModule { } @Provides - public static Storage provideStorage() { - return Context.getDataManager().getStorage(); + public static Storage provideStorage(DataSource dataSource, ObjectMapper objectMapper) { + return new DatabaseStorage(dataSource, objectMapper); } @Provides diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 6921634dd..9ffe1fe97 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -15,16 +15,6 @@ */ package org.traccar.database; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; -import liquibase.Contexts; -import liquibase.Liquibase; -import liquibase.database.Database; -import liquibase.database.DatabaseFactory; -import liquibase.exception.LiquibaseException; -import liquibase.resource.FileSystemResourceAccessor; -import liquibase.resource.ResourceAccessor; import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -34,7 +24,6 @@ import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.storage.DatabaseStorage; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -43,100 +32,18 @@ import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.sql.DataSource; -import java.io.File; -import java.lang.reflect.Method; -import java.net.URL; import java.util.Collection; import java.util.Date; public class DataManager { - private final Config config; - - private DataSource dataSource; - - public DataSource getDataSource() { - return dataSource; - } - private final Storage storage; - public Storage getStorage() { - return storage; - } - private final boolean forceLdap; - public DataManager(Config config) throws Exception { - this.config = config; - + public DataManager(Config config, Storage storage) throws Exception { + this.storage = storage; forceLdap = config.getBoolean(Keys.LDAP_FORCE); - - initDatabase(); - initDatabaseSchema(); - - storage = new DatabaseStorage(dataSource, Main.getInjector().getInstance(ObjectMapper.class)); - } - - private void initDatabase() throws Exception { - - String driverFile = config.getString(Keys.DATABASE_DRIVER_FILE); - if (driverFile != null) { - ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - try { - Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class); - method.setAccessible(true); - method.invoke(classLoader, new File(driverFile).toURI().toURL()); - } catch (NoSuchMethodException e) { - Method method = classLoader.getClass() - .getDeclaredMethod("appendToClassPathForInstrumentation", String.class); - method.setAccessible(true); - method.invoke(classLoader, driverFile); - } - } - - String driver = config.getString(Keys.DATABASE_DRIVER); - if (driver != null) { - Class.forName(driver); - } - - HikariConfig hikariConfig = new HikariConfig(); - hikariConfig.setDriverClassName(driver); - hikariConfig.setJdbcUrl(config.getString(Keys.DATABASE_URL)); - hikariConfig.setUsername(config.getString(Keys.DATABASE_USER)); - hikariConfig.setPassword(config.getString(Keys.DATABASE_PASSWORD)); - hikariConfig.setConnectionInitSql(config.getString(Keys.DATABASE_CHECK_CONNECTION)); - hikariConfig.setIdleTimeout(600000); - - int maxPoolSize = config.getInteger(Keys.DATABASE_MAX_POOL_SIZE); - if (maxPoolSize != 0) { - hikariConfig.setMaximumPoolSize(maxPoolSize); - } - - dataSource = new HikariDataSource(hikariConfig); - } - - private void initDatabaseSchema() throws LiquibaseException { - - if (config.hasKey(Keys.DATABASE_CHANGELOG)) { - - ResourceAccessor resourceAccessor = new FileSystemResourceAccessor(new File(".")); - - Database database = DatabaseFactory.getInstance().openDatabase( - config.getString(Keys.DATABASE_URL), - config.getString(Keys.DATABASE_USER), - config.getString(Keys.DATABASE_PASSWORD), - config.getString(Keys.DATABASE_DRIVER), - null, null, null, resourceAccessor); - - String changelog = config.getString(Keys.DATABASE_CHANGELOG); - - try (Liquibase liquibase = new Liquibase(changelog, resourceAccessor, database)) { - liquibase.clearCheckSums(); - liquibase.update(new Contexts()); - } - } } public User login(String email, String password) throws StorageException { diff --git a/src/main/java/org/traccar/storage/DatabaseModule.java b/src/main/java/org/traccar/storage/DatabaseModule.java new file mode 100644 index 000000000..71bf84b34 --- /dev/null +++ b/src/main/java/org/traccar/storage/DatabaseModule.java @@ -0,0 +1,103 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.storage; + +import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import liquibase.Contexts; +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.exception.LiquibaseException; +import liquibase.resource.FileSystemResourceAccessor; +import liquibase.resource.ResourceAccessor; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Singleton; +import javax.sql.DataSource; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URL; + +public class DatabaseModule extends AbstractModule { + + @Singleton + @Provides + public static DataSource provideDataSource( + Config config) throws ReflectiveOperationException, IOException, LiquibaseException { + + String driverFile = config.getString(Keys.DATABASE_DRIVER_FILE); + if (driverFile != null) { + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + try { + Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class); + method.setAccessible(true); + method.invoke(classLoader, new File(driverFile).toURI().toURL()); + } catch (NoSuchMethodException e) { + Method method = classLoader.getClass() + .getDeclaredMethod("appendToClassPathForInstrumentation", String.class); + method.setAccessible(true); + method.invoke(classLoader, driverFile); + } + } + + String driver = config.getString(Keys.DATABASE_DRIVER); + if (driver != null) { + Class.forName(driver); + } + + HikariConfig hikariConfig = new HikariConfig(); + hikariConfig.setDriverClassName(driver); + hikariConfig.setJdbcUrl(config.getString(Keys.DATABASE_URL)); + hikariConfig.setUsername(config.getString(Keys.DATABASE_USER)); + hikariConfig.setPassword(config.getString(Keys.DATABASE_PASSWORD)); + hikariConfig.setConnectionInitSql(config.getString(Keys.DATABASE_CHECK_CONNECTION)); + hikariConfig.setIdleTimeout(600000); + + int maxPoolSize = config.getInteger(Keys.DATABASE_MAX_POOL_SIZE); + if (maxPoolSize != 0) { + hikariConfig.setMaximumPoolSize(maxPoolSize); + } + + DataSource dataSource = new HikariDataSource(hikariConfig); + + if (config.hasKey(Keys.DATABASE_CHANGELOG)) { + + ResourceAccessor resourceAccessor = new FileSystemResourceAccessor(new File(".")); + + Database database = DatabaseFactory.getInstance().openDatabase( + config.getString(Keys.DATABASE_URL), + config.getString(Keys.DATABASE_USER), + config.getString(Keys.DATABASE_PASSWORD), + config.getString(Keys.DATABASE_DRIVER), + null, null, null, resourceAccessor); + + String changelog = config.getString(Keys.DATABASE_CHANGELOG); + + try (Liquibase liquibase = new Liquibase(changelog, resourceAccessor, database)) { + liquibase.clearCheckSums(); + liquibase.update(new Contexts()); + } + } + + return dataSource; + } + +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 933e8c845..5d20966ad 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -47,7 +47,6 @@ import org.jvnet.hk2.guice.bridge.api.GuiceBridge; import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.LifecycleObject; import org.traccar.Main; import org.traccar.api.DateParameterConverterProvider; @@ -67,6 +66,7 @@ import javax.servlet.ServletException; import javax.servlet.SessionCookieConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.sql.DataSource; import java.io.File; import java.io.IOException; import java.io.Writer; @@ -80,11 +80,13 @@ public class WebServer implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); private final Injector injector; + private final Config config; private final Server server; @Inject public WebServer(Injector injector, Config config) { this.injector = injector; + this.config = config; String address = config.getString(Keys.WEB_ADDRESS); int port = config.getInteger(Keys.WEB_PORT); if (address == null) { @@ -95,14 +97,14 @@ public class WebServer implements LifecycleObject { ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); - initApi(config, servletHandler); - initSessionConfig(config, servletHandler); + initApi(servletHandler); + initSessionConfig(servletHandler); if (config.getBoolean(Keys.WEB_CONSOLE)) { servletHandler.addServlet(new ServletHolder(new ConsoleServlet()), "/console/*"); } - initWebApp(config, servletHandler); + initWebApp(servletHandler); servletHandler.setErrorHandler(new ErrorHandler() { @Override @@ -119,7 +121,7 @@ public class WebServer implements LifecycleObject { }); HandlerList handlers = new HandlerList(); - initClientProxy(config, handlers); + initClientProxy(handlers); handlers.addHandler(servletHandler); handlers.addHandler(new GzipHandler()); server.setHandler(handlers); @@ -133,7 +135,7 @@ public class WebServer implements LifecycleObject { } } - private void initClientProxy(Config config, HandlerList handlers) { + private void initClientProxy(HandlerList handlers) { int port = config.getInteger(Keys.PROTOCOL_PORT.withPrefix("osmand")); if (port != 0) { ServletContextHandler servletHandler = new ServletContextHandler() { @@ -153,7 +155,7 @@ public class WebServer implements LifecycleObject { } } - private void initWebApp(Config config, ServletContextHandler servletHandler) { + private void initWebApp(ServletContextHandler servletHandler) { ServletHolder servletHolder = new ServletHolder(DefaultServlet.class); servletHolder.setInitParameter("resourceBase", new File(config.getString(Keys.WEB_PATH)).getAbsolutePath()); servletHolder.setInitParameter("dirAllowed", "false"); @@ -169,7 +171,7 @@ public class WebServer implements LifecycleObject { servletHandler.addServlet(servletHolder, "/*"); } - private void initApi(Config config, ServletContextHandler servletHandler) { + private void initApi(ServletContextHandler servletHandler) { servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); servletHandler.addServlet(new ServletHolder(injector.getInstance(AsyncSocketServlet.class)), "/api/socket"); @@ -211,10 +213,10 @@ public class WebServer implements LifecycleObject { servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } - private void initSessionConfig(Config config, ServletContextHandler servletHandler) { + private void initSessionConfig(ServletContextHandler servletHandler) { if (config.getBoolean(Keys.WEB_PERSIST_SESSION)) { DatabaseAdaptor databaseAdaptor = new DatabaseAdaptor(); - databaseAdaptor.setDatasource(Context.getDataManager().getDataSource()); + databaseAdaptor.setDatasource(injector.getInstance(DataSource.class)); JDBCSessionDataStoreFactory jdbcSessionDataStoreFactory = new JDBCSessionDataStoreFactory(); jdbcSessionDataStoreFactory.setDatabaseAdaptor(databaseAdaptor); SessionHandler sessionHandler = servletHandler.getSessionHandler(); -- cgit v1.2.3 From d3fd20d4a4f7dc647e75c5a0cb962759630ed967 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 06:51:41 -0700 Subject: Inject data manager --- src/main/java/org/traccar/Context.java | 24 +++++++--------------- src/main/java/org/traccar/MainModule.java | 6 ------ .../java/org/traccar/database/DataManager.java | 8 ++------ 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 00ab05d57..cbbc73d76 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -16,7 +16,6 @@ package org.traccar; import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; @@ -47,12 +46,6 @@ public final class Context { return identityManager; } - private static DataManager dataManager; - - public static DataManager getDataManager() { - return dataManager; - } - private static GroupsManager groupsManager; public static GroupsManager getGroupsManager() { @@ -82,20 +75,17 @@ public final class Context { throw e; } - if (config.hasKey(Keys.DATABASE_URL)) { - dataManager = new DataManager(config, Main.getInjector().getInstance(Storage.class)); - } - - if (dataManager != null) { - groupsManager = new GroupsManager(dataManager); - deviceManager = new DeviceManager( - config, dataManager, Main.getInjector().getInstance(ConnectionManager.class)); - } + groupsManager = new GroupsManager(Main.getInjector().getInstance(DataManager.class)); + deviceManager = new DeviceManager( + config, + Main.getInjector().getInstance(DataManager.class), + Main.getInjector().getInstance(ConnectionManager.class)); identityManager = deviceManager; permissionsManager = new PermissionsManager( - dataManager, Main.getInjector().getInstance(Storage.class)); + Main.getInjector().getInstance(DataManager.class), + Main.getInjector().getInstance(Storage.class)); } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 4e95b2be0..aac11e619 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,7 +30,6 @@ import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; import org.traccar.database.LdapProvider; @@ -114,11 +113,6 @@ public class MainModule extends AbstractModule { return new DatabaseStorage(dataSource, objectMapper); } - @Provides - public static DataManager provideDataManager() { - return Context.getDataManager(); - } - @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 9ffe1fe97..3cad2dd63 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -32,6 +32,7 @@ import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; +import javax.inject.Inject; import java.util.Collection; import java.util.Date; @@ -41,6 +42,7 @@ public class DataManager { private final boolean forceLdap; + @Inject public DataManager(Config config, Storage storage) throws Exception { this.storage = storage; forceLdap = config.getBoolean(Keys.LDAP_FORCE); @@ -68,12 +70,6 @@ public class DataManager { return null; } - public void updateUserPassword(User user) throws StorageException { - storage.updateObject(user, new Request( - new Columns.Include("hashedPassword", "salt"), - new Condition.Equals("id", "id"))); - } - public void updateDeviceStatus(Device device) throws StorageException { storage.updateObject(device, new Request( new Columns.Include("lastUpdate"), -- cgit v1.2.3 From d3e83f9fa0d066e5a15fde225599cc43071c031a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 07:09:00 -0700 Subject: Remove groups manager --- src/main/java/org/traccar/Context.java | 13 +-- src/main/java/org/traccar/WebDataHandler.java | 8 +- .../java/org/traccar/api/BaseObjectResource.java | 11 +- .../java/org/traccar/database/DeviceManager.java | 9 +- .../traccar/database/ExtendedObjectManager.java | 115 --------------------- .../java/org/traccar/database/GroupsManager.java | 64 ------------ .../org/traccar/database/PermissionsManager.java | 11 +- .../org/traccar/reports/EventsReportProvider.java | 5 +- .../org/traccar/reports/RouteReportProvider.java | 8 +- .../org/traccar/reports/StopsReportProvider.java | 8 +- .../org/traccar/reports/TripsReportProvider.java | 8 +- src/test/java/org/traccar/WebDataHandlerTest.java | 3 +- 12 files changed, 48 insertions(+), 215 deletions(-) delete mode 100644 src/main/java/org/traccar/database/ExtendedObjectManager.java delete mode 100644 src/main/java/org/traccar/database/GroupsManager.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index cbbc73d76..9e8e3c521 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -19,14 +19,13 @@ import org.traccar.config.Config; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Group; import org.traccar.session.ConnectionManager; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.Storage; public final class Context { @@ -46,12 +45,6 @@ public final class Context { return identityManager; } - private static GroupsManager groupsManager; - - public static GroupsManager getGroupsManager() { - return groupsManager; - } - private static DeviceManager deviceManager; public static DeviceManager getDeviceManager() { @@ -75,9 +68,9 @@ public final class Context { throw e; } - groupsManager = new GroupsManager(Main.getInjector().getInstance(DataManager.class)); deviceManager = new DeviceManager( config, + Main.getInjector().getInstance(CacheManager.class), Main.getInjector().getInstance(DataManager.class), Main.getInjector().getInstance(ConnectionManager.class)); @@ -92,8 +85,6 @@ public final class Context { public static BaseObjectManager getManager(Class clazz) { if (clazz.equals(Device.class)) { return (BaseObjectManager) deviceManager; - } else if (clazz.equals(Group.class)) { - return (BaseObjectManager) groupsManager; } return null; } diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index 2c0aa0f8e..db99ecaf8 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -31,6 +31,7 @@ import org.traccar.helper.Checksum; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.Group; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.ws.rs.core.HttpHeaders; @@ -60,6 +61,7 @@ public class WebDataHandler extends BaseDataHandler { private static final String KEY_POSITION = "position"; private static final String KEY_DEVICE = "device"; + private final CacheManager cacheManager; private final IdentityManager identityManager; private final ObjectMapper objectMapper; private final Client client; @@ -78,8 +80,10 @@ public class WebDataHandler extends BaseDataHandler { @Inject public WebDataHandler( - Config config, IdentityManager identityManager, ObjectMapper objectMapper, Client client) { + Config config, CacheManager cacheManager, IdentityManager identityManager, + ObjectMapper objectMapper, Client client) { + this.cacheManager = cacheManager; this.identityManager = identityManager; this.objectMapper = objectMapper; this.client = client; @@ -171,7 +175,7 @@ public class WebDataHandler extends BaseDataHandler { if (request.contains("{group}")) { String deviceGroupName = ""; if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + Group group = cacheManager.getObject(Group.class, device.getGroupId()); if (group != null) { deviceGroupName = group.getName(); } diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index f8545a5d7..78aa12dbe 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -18,7 +18,6 @@ package org.traccar.api; import org.traccar.Context; import org.traccar.database.BaseObjectManager; -import org.traccar.database.ExtendedObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -92,10 +91,16 @@ public abstract class BaseObjectResource extends BaseResour public Response update(T entity) throws StorageException { permissionsService.checkEdit(getUserId(), entity, false); permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); + if (entity instanceof User) { User before = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); permissionsService.checkUserUpdate(getUserId(), before, (User) entity); + } else if (entity instanceof Group) { + Group group = (Group) entity; + if (group.getId() == group.getGroupId()) { + throw new IllegalArgumentException("Cycle in group hierarchy"); + } } BaseObjectManager manager = Context.getManager(baseClass); @@ -125,9 +130,6 @@ public abstract class BaseObjectResource extends BaseResour BaseObjectManager manager = Context.getManager(baseClass); if (manager != null) { manager.removeItem(id); - if (manager instanceof ExtendedObjectManager) { - ((ExtendedObjectManager) manager).refreshExtendedPermissions(); - } } else { storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); } @@ -137,7 +139,6 @@ public abstract class BaseObjectResource extends BaseResour if (baseClass.equals(Group.class) || baseClass.equals(Device.class) || baseClass.equals(User.class)) { if (baseClass.equals(Group.class)) { - Context.getGroupsManager().refreshItems(); Context.getDeviceManager().updateDeviceCache(true); } Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 9ba486988..29c17c41f 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -46,6 +46,7 @@ public class DeviceManager extends BaseObjectManager implements Identity private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); private final Config config; + private final CacheManager cacheManager; private final ConnectionManager connectionManager; private final long dataRefreshDelay; @@ -56,9 +57,11 @@ public class DeviceManager extends BaseObjectManager implements Identity private final Map deviceStates = new ConcurrentHashMap<>(); - public DeviceManager(Config config, DataManager dataManager, ConnectionManager connectionManager) { + public DeviceManager( + Config config, CacheManager cacheManager, DataManager dataManager, ConnectionManager connectionManager) { super(dataManager, Device.class); this.config = config; + this.cacheManager = cacheManager; this.connectionManager = connectionManager; try { writeLock(); @@ -351,8 +354,8 @@ public class DeviceManager extends BaseObjectManager implements Identity result = device.getAttributes().get(attributeName); if (result == null) { long groupId = device.getGroupId(); - while (groupId != 0) { - Group group = Context.getGroupsManager().getById(groupId); + while (groupId > 0) { + Group group = cacheManager.getObject(Group.class, device.getGroupId()); if (group != null) { result = group.getAttributes().get(attributeName); if (result != null) { diff --git a/src/main/java/org/traccar/database/ExtendedObjectManager.java b/src/main/java/org/traccar/database/ExtendedObjectManager.java deleted file mode 100644 index fe0ebb96e..000000000 --- a/src/main/java/org/traccar/database/ExtendedObjectManager.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.database; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.model.Permission; -import org.traccar.model.BaseModel; -import org.traccar.storage.StorageException; - -public abstract class ExtendedObjectManager extends SimpleObjectManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(ExtendedObjectManager.class); - - private final Map> deviceItems = new ConcurrentHashMap<>(); - private final Map> deviceItemsWithGroups = new ConcurrentHashMap<>(); - private final Map> groupItems = new ConcurrentHashMap<>(); - - protected ExtendedObjectManager(DataManager dataManager, Class baseClass) { - super(dataManager, baseClass); - refreshExtendedPermissions(); - } - - public Set getAllDeviceItems(long deviceId) { - try { - readLock(); - Set result = deviceItemsWithGroups.get(deviceId); - if (result != null) { - return new HashSet<>(result); - } else { - return new HashSet<>(); - } - } finally { - readUnlock(); - } - } - - @Override - public void removeItem(long itemId) throws StorageException { - super.removeItem(itemId); - refreshExtendedPermissions(); - } - - public void refreshExtendedPermissions() { - if (getDataManager() != null) { - try { - Collection databaseGroupPermissions = - getDataManager().getPermissions(Group.class, getBaseClass()); - - Collection databaseDevicePermissions = - getDataManager().getPermissions(Device.class, getBaseClass()); - - writeLock(); - - groupItems.clear(); - deviceItems.clear(); - deviceItemsWithGroups.clear(); - - for (Permission groupPermission : databaseGroupPermissions) { - groupItems - .computeIfAbsent(groupPermission.getOwnerId(), key -> new HashSet<>()) - .add(groupPermission.getPropertyId()); - } - - for (Permission devicePermission : databaseDevicePermissions) { - deviceItems - .computeIfAbsent(devicePermission.getOwnerId(), key -> new HashSet<>()) - .add(devicePermission.getPropertyId()); - deviceItemsWithGroups - .computeIfAbsent(devicePermission.getOwnerId(), key -> new HashSet<>()) - .add(devicePermission.getPropertyId()); - } - - for (Device device : getDataManager().getObjects(Device.class)) { - long groupId = device.getGroupId(); - while (groupId > 0) { - deviceItemsWithGroups - .computeIfAbsent(device.getId(), key -> new HashSet<>()) - .addAll(groupItems.getOrDefault(groupId, new HashSet<>())); - Group group = Context.getGroupsManager().getById(groupId); - groupId = group != null ? group.getGroupId() : 0; - } - } - - } catch (StorageException | ClassNotFoundException error) { - LOGGER.warn("Refresh permissions error", error); - } finally { - writeUnlock(); - } - } - } -} diff --git a/src/main/java/org/traccar/database/GroupsManager.java b/src/main/java/org/traccar/database/GroupsManager.java deleted file mode 100644 index 4df848042..000000000 --- a/src/main/java/org/traccar/database/GroupsManager.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.database; - -import java.util.HashSet; -import java.util.Set; - -import org.traccar.model.Group; -import org.traccar.storage.StorageException; - -public class GroupsManager extends BaseObjectManager { - - public GroupsManager(DataManager dataManager) { - super(dataManager, Group.class); - } - - private void checkGroupCycles(Group group) { - Set groups = new HashSet<>(); - while (group != null) { - if (groups.contains(group.getId())) { - throw new IllegalArgumentException("Cycle in group hierarchy"); - } - groups.add(group.getId()); - group = getById(group.getGroupId()); - } - } - - @Override - public Set getAllItems() { - Set result = super.getAllItems(); - if (result.isEmpty()) { - refreshItems(); - result = super.getAllItems(); - } - return result; - } - - @Override - protected void addNewItem(Group group) { - checkGroupCycles(group); - super.addNewItem(group); - } - - @Override - public void updateItem(Group group) throws StorageException { - checkGroupCycles(group); - super.updateItem(group); - } - -} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 833480eea..595e236fa 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -162,9 +162,8 @@ public class PermissionsManager { groupPermissions.clear(); devicePermissions.clear(); try { - GroupTree groupTree = new GroupTree(Context.getGroupsManager().getItems( - Context.getGroupsManager().getAllItems()), - Context.getDeviceManager().getAllDevices()); + var groups = dataManager.getObjects(Group.class); + GroupTree groupTree = new GroupTree(groups, Context.getDeviceManager().getAllDevices()); for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) { Set userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId()); Set userDevicePermissions = getDevicePermissions(groupPermission.getOwnerId()); @@ -182,9 +181,9 @@ public class PermissionsManager { } groupDevices.clear(); - for (long groupId : Context.getGroupsManager().getAllItems()) { - for (Device device : groupTree.getDevices(groupId)) { - getGroupDevices(groupId).add(device.getId()); + for (var group : groups) { + for (Device device : groupTree.getDevices(group.getId())) { + getGroupDevices(group.getId()).add(device.getId()); } } diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 5148695a9..b1f7149a2 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -134,8 +134,9 @@ public class EventsReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceEvents.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index b1a806960..903dfe369 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -28,6 +28,9 @@ import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -77,8 +80,9 @@ public class RouteReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceRoutes.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index a6a9a94cc..b9d36eb97 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -28,6 +28,9 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -85,8 +88,9 @@ public class StopsReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceStops.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index bff559664..97cfccf74 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -28,6 +28,9 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -85,8 +88,9 @@ public class TripsReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceTrips.setGroupName(group.getName()); } diff --git a/src/test/java/org/traccar/WebDataHandlerTest.java b/src/test/java/org/traccar/WebDataHandlerTest.java index aaec9f530..ff9c80ce6 100644 --- a/src/test/java/org/traccar/WebDataHandlerTest.java +++ b/src/test/java/org/traccar/WebDataHandlerTest.java @@ -6,6 +6,7 @@ import org.traccar.config.Keys; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyLong; @@ -30,7 +31,7 @@ public class WebDataHandlerTest extends ProtocolTest { var identityManager = mock(IdentityManager.class); when(identityManager.getById(anyLong())).thenReturn(device); - WebDataHandler handler = new WebDataHandler(config, identityManager, null, null); + WebDataHandler handler = new WebDataHandler(config, mock(CacheManager.class), identityManager, null, null); assertEquals( "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", -- cgit v1.2.3 From cc342a9ba371b0dca8d87ca9e74c5907ccb58bc6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 07:18:33 -0700 Subject: Permissions manager refactor --- .../traccar/api/resource/PermissionsResource.java | 5 ++-- .../org/traccar/api/resource/ServerResource.java | 4 +--- .../java/org/traccar/database/DeviceManager.java | 2 +- .../org/traccar/database/PermissionsManager.java | 27 ---------------------- .../org/traccar/session/ConnectionManager.java | 14 +++++------ 5 files changed, 12 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 36ee0c213..b92e6e9d9 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -20,6 +20,7 @@ import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Permission; +import org.traccar.model.UserRestrictions; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; @@ -65,7 +66,7 @@ public class PermissionsResource extends BaseResource { @Path("bulk") @POST public Response add(List> entities) throws StorageException, ClassNotFoundException { - Context.getPermissionsManager().checkReadonly(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); checkPermissionTypes(entities); for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); @@ -90,7 +91,7 @@ public class PermissionsResource extends BaseResource { @DELETE @Path("bulk") public Response remove(List> entities) throws StorageException, ClassNotFoundException { - Context.getPermissionsManager().checkReadonly(getUserId()); + permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); checkPermissionTypes(entities); for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 18230a2b3..b66f5a931 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -15,7 +15,6 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.database.MailManager; import org.traccar.geocoder.Geocoder; @@ -66,8 +65,7 @@ public class ServerResource extends BaseResource { @PUT public Response update(Server entity) throws StorageException { - Context.getPermissionsManager().checkAdmin(getUserId()); - Context.getPermissionsManager().updateServer(entity); + permissionsService.checkAdmin(getUserId()); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 29c17c41f..bd100245c 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -368,7 +368,7 @@ public class DeviceManager extends BaseObjectManager implements Identity } } if (result == null && lookupServer) { - Server server = Context.getPermissionsManager().getServer(); + Server server = cacheManager.getServer(); result = server.getAttributes().get(attributeName); } if (result == null && lookupConfig) { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 595e236fa..3d4e6425a 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -22,7 +22,6 @@ import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; -import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -44,8 +43,6 @@ public class PermissionsManager { private final DataManager dataManager; private final Storage storage; - private volatile Server server; - private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Map> groupPermissions = new HashMap<>(); @@ -56,7 +53,6 @@ public class PermissionsManager { public PermissionsManager(DataManager dataManager, Storage storage) { this.dataManager = dataManager; this.storage = storage; - refreshServer(); refreshDeviceAndGroupPermissions(); } @@ -148,14 +144,6 @@ public class PermissionsManager { } } - public void refreshServer() { - try { - server = dataManager.getServer(); - } catch (StorageException error) { - LOGGER.warn("Refresh server config error", error); - } - } - public final void refreshDeviceAndGroupPermissions() { writeLock(); try { @@ -229,12 +217,6 @@ public class PermissionsManager { return user != null && user.getReadonly(); } - public void checkReadonly(long userId) throws SecurityException { - if (!getUserAdmin(userId) && (server.getReadonly() || getUserReadonly(userId))) { - throw new SecurityException("Account is readonly"); - } - } - public void checkUserEnabled(long userId) throws SecurityException { User user = getUser(userId); if (user == null) { @@ -265,15 +247,6 @@ public class PermissionsManager { } } - public Server getServer() { - return server; - } - - public void updateServer(Server server) throws StorageException { - dataManager.updateObject(server); - this.server = server; - } - public User login(String email, String password) throws StorageException { User user = dataManager.login(email, password); if (user != null) { diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index dc714379b..c8c07f9c7 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -31,6 +31,7 @@ import org.traccar.handler.events.OverspeedEventHandler; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.session.cache.CacheManager; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -297,9 +298,9 @@ public class ConnectionManager { } public synchronized void updateDevice(Device device) { - for (long userId : Context.getPermissionsManager().getDeviceUsers(device.getId())) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { + for (User user : cacheManager.getDeviceObjects(device.getId(), User.class)) { + if (listeners.containsKey(user.getId())) { + for (UpdateListener listener : listeners.get(user.getId())) { listener.onUpdateDevice(device); } } @@ -308,10 +309,9 @@ public class ConnectionManager { public synchronized void updatePosition(Position position) { long deviceId = position.getDeviceId(); - - for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) { - if (listeners.containsKey(userId)) { - for (UpdateListener listener : listeners.get(userId)) { + for (User user : cacheManager.getDeviceObjects(deviceId, User.class)) { + if (listeners.containsKey(user.getId())) { + for (UpdateListener listener : listeners.get(user.getId())) { listener.onUpdatePosition(position); } } -- cgit v1.2.3 From e74c64f27dc30473d9ef866c5c52e3dd6bee2fc3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 07:45:19 -0700 Subject: Refactor device permissions check --- src/main/java/org/traccar/api/MediaFilter.java | 23 ++++++++++---- .../org/traccar/api/resource/EventResource.java | 4 +-- .../traccar/api/security/PermissionsService.java | 13 ++++++++ .../org/traccar/database/PermissionsManager.java | 35 ---------------------- .../org/traccar/reports/EventsReportProvider.java | 6 ++-- .../org/traccar/reports/RouteReportProvider.java | 6 ++-- .../org/traccar/reports/StopsReportProvider.java | 6 ++-- .../org/traccar/reports/SummaryReportProvider.java | 4 +-- .../org/traccar/reports/TripsReportProvider.java | 6 ++-- .../org/traccar/reports/common/ReportUtils.java | 12 ++++++++ 10 files changed, 62 insertions(+), 53 deletions(-) diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index 0433147f8..c6ac811d7 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -28,12 +28,17 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.traccar.Context; import org.traccar.Main; import org.traccar.api.resource.SessionResource; +import org.traccar.api.security.PermissionsService; import org.traccar.database.StatisticsManager; import org.traccar.helper.Log; import org.traccar.model.Device; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; public class MediaFilter implements Filter { @@ -44,6 +49,11 @@ public class MediaFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + + PermissionsService permissionsService = Main.getInjector().getInstance(PermissionsService.class); + Storage storage = Main.getInjector().getInstance(Storage.class); + StatisticsManager statisticsManager = Main.getInjector().getInstance(StatisticsManager.class); + HttpServletResponse httpResponse = (HttpServletResponse) response; try { HttpSession session = ((HttpServletRequest) request).getSession(false); @@ -51,8 +61,8 @@ public class MediaFilter implements Filter { if (session != null) { userId = (Long) session.getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { - Context.getPermissionsManager().checkUserEnabled(userId); - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); + permissionsService.checkUserEnabled(userId); + statisticsManager.registerRequest(userId); } } if (userId == null) { @@ -63,16 +73,17 @@ public class MediaFilter implements Filter { String path = ((HttpServletRequest) request).getPathInfo(); String[] parts = path != null ? path.split("/") : null; if (parts != null && parts.length >= 2) { - Device device = Context.getDeviceManager().getByUniqueId(parts[1]); + Device device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", parts[1]))); if (device != null) { - Context.getPermissionsManager().checkDevice(userId, device.getId()); + permissionsService.checkPermission(Device.class, userId, device.getId()); chain.doFilter(request, response); return; } } httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN); - } catch (SecurityException e) { + } catch (SecurityException | StorageException e) { httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); httpResponse.getWriter().println(Log.exceptionStack(e)); } diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index eb373946a..3870e9af9 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -15,8 +15,8 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -45,7 +45,7 @@ public class EventResource extends BaseResource { if (event == null) { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } - Context.getPermissionsManager().checkDevice(getUserId(), event.getDeviceId()); + permissionsService.checkPermission(Device.class, getUserId(), event.getDeviceId()); return event; } diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index f39ded2b7..8732a0d04 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -92,6 +92,19 @@ public class PermissionsService { } } + public void checkUserEnabled(long userId) throws StorageException, SecurityException { + User user = getUser(userId); + if (user == null) { + throw new SecurityException("Unknown account"); + } + if (user.getDisabled()) { + throw new SecurityException("Account is disabled"); + } + if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { + throw new SecurityException("Account has expired"); + } + } + public void checkEdit(long userId, Class clazz, boolean addition) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { boolean denied = false; diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 3d4e6425a..f6fbd9489 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -18,7 +18,6 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; -import org.traccar.api.security.PermissionsService; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; @@ -117,21 +116,6 @@ public class PermissionsManager { } } - public Set getDeviceUsers(long deviceId) { - Device device = Context.getIdentityManager().getById(deviceId); - if (device != null && !device.getDisabled()) { - return getAllDeviceUsers(deviceId); - } else { - Set result = new HashSet<>(); - for (long userId : getAllDeviceUsers(deviceId)) { - if (getUserAdmin(userId)) { - result.add(userId); - } - } - return result; - } - } - public Set getGroupDevices(long groupId) { readLock(); try { @@ -195,12 +179,6 @@ public class PermissionsManager { return user != null && user.getAdministrator(); } - public void checkAdmin(long userId) throws SecurityException { - if (!getUserAdmin(userId)) { - throw new SecurityException("Admin access required"); - } - } - public boolean getUserManager(long userId) { User user = getUser(userId); return user != null && user.getUserLimit() != 0; @@ -212,11 +190,6 @@ public class PermissionsManager { } } - public boolean getUserReadonly(long userId) { - User user = getUser(userId); - return user != null && user.getReadonly(); - } - public void checkUserEnabled(long userId) throws SecurityException { User user = getUser(userId); if (user == null) { @@ -230,14 +203,6 @@ public class PermissionsManager { } } - public void checkDevice(long userId, long deviceId) throws SecurityException { - try { - new PermissionsService(storage).checkPermission(Device.class, userId, deviceId); - } catch (StorageException e) { - throw new RuntimeException(e); - } - } - public void refreshPermissions(Permission permission) { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index b1f7149a2..4db842fdb 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -74,9 +74,10 @@ public class EventsReportProvider { long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); Collection events = getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Event event : events) { @@ -98,12 +99,13 @@ public class EventsReportProvider { OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList devicesEvents = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); Collection events = getEvents(deviceId, from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Iterator iterator = events.iterator(); iterator.hasNext();) { diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 903dfe369..b4401bc87 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -59,9 +59,10 @@ public class RouteReportProvider { public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(PositionUtil.getPositions(storage, deviceId, from, to)); } return result; @@ -71,10 +72,11 @@ public class RouteReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); var positions = PositionUtil.getPositions(storage, deviceId, from, to); DeviceReportSection deviceRoutes = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index b9d36eb97..a63d7ee21 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -67,9 +67,10 @@ public class StopsReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectStops(deviceId, from, to)); } return result; @@ -79,10 +80,11 @@ public class StopsReportProvider { OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); Collection stops = detectStops(deviceId, from, to); DeviceReportSection deviceStops = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 68976b987..86d76b4e3 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -146,9 +146,10 @@ public class SummaryReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); for (SummaryReportItem summaryReport : deviceResults) { if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { @@ -162,7 +163,6 @@ public class SummaryReportProvider { public void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException, IOException { - reportUtils.checkPeriodLimit(from, to); Collection summaries = getObjects(userId, deviceIds, groupIds, from, to, daily); File file = Paths.get(config.getString(Keys.TEMPLATES_ROOT), "export", "summary.xlsx").toFile(); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 97cfccf74..bec4c39fd 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -67,9 +67,10 @@ public class TripsReportProvider { public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList result = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); result.addAll(detectTrips(deviceId, from, to)); } return result; @@ -79,10 +80,11 @@ public class TripsReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); + reportUtils.checkPermissions(userId, deviceIds, groupIds); + ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Context.getPermissionsManager().checkDevice(userId, deviceId); Collection trips = detectTrips(deviceId, from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); Device device = Context.getIdentityManager().getById(deviceId); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 95c43f8a0..84866a67b 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -38,8 +38,10 @@ import org.traccar.helper.UnitsConverter; import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; +import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Event; +import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.reports.model.BaseReportItem; @@ -109,6 +111,16 @@ public class ReportUtils { } } + public void checkPermissions( + long userId, Collection deviceIds, Collection groupIds) throws StorageException { + for (long deviceId : deviceIds) { + permissionsService.checkPermission(Device.class, userId, deviceId); + } + for (long groupId : groupIds) { + permissionsService.checkPermission(Group.class, userId, groupId); + } + } + public Collection getDeviceList(Collection deviceIds, Collection groupIds) { Collection result = new LinkedHashSet<>(deviceIds); for (long groupId : groupIds) { -- cgit v1.2.3 From 51cdee534cd9990d1de173814fe95c55dead4934 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 08:24:48 -0700 Subject: Refactor login --- src/main/java/org/traccar/api/MediaFilter.java | 1 - .../org/traccar/api/resource/SessionResource.java | 23 +++--- .../traccar/api/security/PermissionsService.java | 13 ---- .../api/security/SecurityRequestFilter.java | 7 +- .../java/org/traccar/database/DataManager.java | 31 +------- .../java/org/traccar/database/LoginService.java | 89 ++++++++++++++++++++++ .../org/traccar/database/PermissionsManager.java | 22 ------ 7 files changed, 104 insertions(+), 82 deletions(-) create mode 100644 src/main/java/org/traccar/database/LoginService.java diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index c6ac811d7..e0609871a 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -61,7 +61,6 @@ public class MediaFilter implements Filter { if (session != null) { userId = (Long) session.getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { - permissionsService.checkUserEnabled(userId); statisticsManager.registerRequest(userId); } } diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index a0bf0cba5..70561f997 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -15,18 +15,16 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.LoginService; import org.traccar.helper.DataConverter; import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; import org.traccar.model.User; import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; +import javax.inject.Inject; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; @@ -54,6 +52,9 @@ public class SessionResource extends BaseResource { public static final String USER_COOKIE_KEY = "user"; public static final String PASS_COOKIE_KEY = "password"; + @Inject + private LoginService loginService; + @javax.ws.rs.core.Context private HttpServletRequest request; @@ -62,11 +63,10 @@ public class SessionResource extends BaseResource { public User get(@QueryParam("token") String token) throws StorageException, UnsupportedEncodingException { if (token != null) { - User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("token", "token", token))); + User user = loginService.login(token); if (user != null) { - Context.getPermissionsManager().checkUserEnabled(user.getId()); request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); return user; } } @@ -90,18 +90,17 @@ public class SessionResource extends BaseResource { } } if (email != null && password != null) { - User user = Context.getPermissionsManager().login(email, password); + User user = loginService.login(email, password); if (user != null) { - Context.getPermissionsManager().checkUserEnabled(user.getId()); request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); return user; } } } else { - Context.getPermissionsManager().checkUserEnabled(userId); - return Context.getPermissionsManager().getUser(userId); + return permissionsService.getUser(userId); } @@ -112,7 +111,7 @@ public class SessionResource extends BaseResource { @POST public User add( @FormParam("email") String email, @FormParam("password") String password) throws StorageException { - User user = Context.getPermissionsManager().login(email, password); + User user = loginService.login(email, password); if (user != null) { request.getSession().setAttribute(USER_ID_KEY, user.getId()); LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 8732a0d04..f39ded2b7 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -92,19 +92,6 @@ public class PermissionsService { } } - public void checkUserEnabled(long userId) throws StorageException, SecurityException { - User user = getUser(userId); - if (user == null) { - throw new SecurityException("Unknown account"); - } - if (user.getDisabled()) { - throw new SecurityException("Account is disabled"); - } - if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { - throw new SecurityException("Account has expired"); - } - } - public void checkEdit(long userId, Class clazz, boolean addition) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { boolean denied = false; diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index 9f20acb40..ad45dc112 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,9 @@ package org.traccar.api.security; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.Main; import org.traccar.api.resource.SessionResource; +import org.traccar.database.LoginService; import org.traccar.database.StatisticsManager; import org.traccar.helper.DataConverter; import org.traccar.model.User; @@ -77,7 +77,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { try { String[] auth = decodeBasicAuth(authHeader); - User user = Context.getPermissionsManager().login(auth[0], auth[1]); + User user = Main.getInjector().getInstance(LoginService.class).login(auth[0], auth[1]); if (user != null) { Main.getInjector().getInstance(StatisticsManager.class).registerRequest(user.getId()); securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); @@ -90,7 +90,6 @@ public class SecurityRequestFilter implements ContainerRequestFilter { Long userId = (Long) request.getSession().getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { - Context.getPermissionsManager().checkUserEnabled(userId); Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); securityContext = new UserSecurityContext(new UserPrincipal(userId)); } diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 3cad2dd63..aa600e375 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -15,15 +15,11 @@ */ package org.traccar.database; -import org.traccar.Main; -import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; -import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -40,34 +36,9 @@ public class DataManager { private final Storage storage; - private final boolean forceLdap; - @Inject - public DataManager(Config config, Storage storage) throws Exception { + public DataManager(Storage storage) throws Exception { this.storage = storage; - forceLdap = config.getBoolean(Keys.LDAP_FORCE); - } - - public User login(String email, String password) throws StorageException { - User user = storage.getObject(User.class, new Request( - new Columns.Include("id", "login", "hashedPassword", "salt"), - new Condition.Or( - new Condition.Equals("email", "email", email.trim()), - new Condition.Equals("login", "email")))); - LdapProvider ldapProvider = Main.getInjector().getInstance(LdapProvider.class); - if (user != null) { - if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) - || !forceLdap && user.isPasswordValid(password)) { - return user; - } - } else { - if (ldapProvider != null && ldapProvider.login(email, password)) { - user = ldapProvider.getUser(email); - user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); - return user; - } - } - return null; } public void updateDeviceStatus(Device device) throws StorageException { diff --git a/src/main/java/org/traccar/database/LoginService.java b/src/main/java/org/traccar/database/LoginService.java new file mode 100644 index 000000000..a30e443b5 --- /dev/null +++ b/src/main/java/org/traccar/database/LoginService.java @@ -0,0 +1,89 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.database; + +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.annotation.Nullable; +import javax.inject.Inject; + +public class LoginService { + + private final Storage storage; + private final LdapProvider ldapProvider; + + private final boolean forceLdap; + + @Inject + public LoginService(Config config, Storage storage, @Nullable LdapProvider ldapProvider) { + this.storage = storage; + this.ldapProvider = ldapProvider; + forceLdap = config.getBoolean(Keys.LDAP_FORCE); + } + + public User login(String token) throws StorageException { + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("token", "token", token))); + if (user != null) { + checkUserEnabled(user); + } + return user; + } + + public User login(String email, String password) throws StorageException { + User user = storage.getObject(User.class, new Request( + new Columns.Include("id", "login", "hashedPassword", "salt"), + new Condition.Or( + new Condition.Equals("email", "email", email.trim()), + new Condition.Equals("login", "email")))); + if (user != null) { + if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) + || !forceLdap && user.isPasswordValid(password)) { + checkUserEnabled(user); + return user; + } + } else { + if (ldapProvider != null && ldapProvider.login(email, password)) { + user = ldapProvider.getUser(email); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); + checkUserEnabled(user); + return user; + } + } + return null; + } + + + private void checkUserEnabled(User user) throws SecurityException { + if (user == null) { + throw new SecurityException("Unknown account"); + } + if (user.getDisabled()) { + throw new SecurityException("Account is disabled"); + } + if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { + throw new SecurityException("Account has expired"); + } + } + +} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index f6fbd9489..4ac27c717 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -190,19 +190,6 @@ public class PermissionsManager { } } - public void checkUserEnabled(long userId) throws SecurityException { - User user = getUser(userId); - if (user == null) { - throw new SecurityException("Unknown account"); - } - if (user.getDisabled()) { - throw new SecurityException("Account is disabled"); - } - if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { - throw new SecurityException("Account has expired"); - } - } - public void refreshPermissions(Permission permission) { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) @@ -212,13 +199,4 @@ public class PermissionsManager { } } - public User login(String email, String password) throws StorageException { - User user = dataManager.login(email, password); - if (user != null) { - checkUserEnabled(user.getId()); - return getUser(user.getId()); - } - return null; - } - } -- cgit v1.2.3 From b47eca7a90438e738eb1486664717cccc277865f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 15:07:29 -0700 Subject: Refactor web server code --- src/main/java/org/traccar/LifecycleObject.java | 2 +- src/main/java/org/traccar/Main.java | 6 ++- src/main/java/org/traccar/ServerManager.java | 11 +++-- .../org/traccar/web/GuiceBridgeInitializer.java | 49 ++++++++++++++++++++++ src/main/java/org/traccar/web/WebServer.java | 49 ++++------------------ 5 files changed, 70 insertions(+), 47 deletions(-) create mode 100644 src/main/java/org/traccar/web/GuiceBridgeInitializer.java diff --git a/src/main/java/org/traccar/LifecycleObject.java b/src/main/java/org/traccar/LifecycleObject.java index 7af21d528..fe0dc698a 100644 --- a/src/main/java/org/traccar/LifecycleObject.java +++ b/src/main/java/org/traccar/LifecycleObject.java @@ -17,5 +17,5 @@ package org.traccar; public interface LifecycleObject { void start() throws Exception; - void stop(); + void stop() throws Exception; } diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 72eeb5885..e3286fd5e 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -137,7 +137,11 @@ public final class Main { LOGGER.info("Stopping server..."); for (var service : services) { - service.stop(); + try { + service.stop(); + } catch (Exception e) { + throw new RuntimeException(e); + } } })); } catch (Exception e) { diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index ffb15d8ca..99fb9a494 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -72,11 +72,14 @@ public class ServerManager implements LifecycleObject { } @Override - public void stop() { - for (TrackerConnector connector: connectorList) { - connector.stop(); + public void stop() throws Exception { + try { + for (TrackerConnector connector : connectorList) { + connector.stop(); + } + } finally { + GlobalTimer.release(); } - GlobalTimer.release(); } } diff --git a/src/main/java/org/traccar/web/GuiceBridgeInitializer.java b/src/main/java/org/traccar/web/GuiceBridgeInitializer.java new file mode 100644 index 000000000..fc9c88f3b --- /dev/null +++ b/src/main/java/org/traccar/web/GuiceBridgeInitializer.java @@ -0,0 +1,49 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.web; + +import com.google.inject.Injector; +import org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager; +import org.glassfish.jersey.server.spi.Container; +import org.glassfish.jersey.server.spi.ContainerLifecycleListener; +import org.jvnet.hk2.guice.bridge.api.GuiceBridge; +import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; + +public class GuiceBridgeInitializer implements ContainerLifecycleListener { + + private final Injector injector; + + public GuiceBridgeInitializer(Injector injector) { + this.injector = injector; + } + + @Override + public void onStartup(Container container) { + var injectionManager = container.getApplicationHandler().getInjectionManager(); + var serviceLocator = ((ImmediateHk2InjectionManager) injectionManager).getServiceLocator(); + GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator); + var guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class); + guiceBridge.bridgeGuiceInjector(injector); + } + + @Override + public void onReload(Container container) { + } + + @Override + public void onShutdown(Container container) { + } +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 5d20966ad..36f3d7682 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -37,27 +37,21 @@ import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; -import org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.server.spi.Container; -import org.glassfish.jersey.server.spi.ContainerLifecycleListener; import org.glassfish.jersey.servlet.ServletContainer; -import org.jvnet.hk2.guice.bridge.api.GuiceBridge; -import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; -import org.traccar.Main; -import org.traccar.api.DateParameterConverterProvider; -import org.traccar.config.Config; import org.traccar.api.AsyncSocketServlet; import org.traccar.api.CorsResponseFilter; +import org.traccar.api.DateParameterConverterProvider; import org.traccar.api.MediaFilter; import org.traccar.api.ObjectMapperProvider; import org.traccar.api.ResourceErrorHandler; -import org.traccar.api.security.SecurityRequestFilter; import org.traccar.api.resource.ServerResource; +import org.traccar.api.security.SecurityRequestFilter; +import org.traccar.config.Config; import org.traccar.config.Keys; import javax.inject.Inject; @@ -77,8 +71,6 @@ import java.util.EnumSet; public class WebServer implements LifecycleObject { - private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); - private final Injector injector; private final Config config; private final Server server; @@ -192,24 +184,7 @@ public class WebServer implements LifecycleObject { JacksonFeature.class, ObjectMapperProvider.class, ResourceErrorHandler.class, SecurityRequestFilter.class, CorsResponseFilter.class, DateParameterConverterProvider.class); resourceConfig.packages(ServerResource.class.getPackage().getName()); - resourceConfig.register(new ContainerLifecycleListener() { - @Override - public void onStartup(Container container) { - var injectionManager = container.getApplicationHandler().getInjectionManager(); - var serviceLocator = ((ImmediateHk2InjectionManager) injectionManager).getServiceLocator(); - GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator); - var guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class); - guiceBridge.bridgeGuiceInjector(Main.getInjector()); - } - - @Override - public void onReload(Container container) { - } - - @Override - public void onShutdown(Container container) { - } - }); + resourceConfig.register(new GuiceBridgeInitializer(injector)); servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } @@ -251,21 +226,13 @@ public class WebServer implements LifecycleObject { } @Override - public void start() { - try { - server.start(); - } catch (Exception error) { - LOGGER.warn("Web server start failed", error); - } + public void start() throws Exception { + server.start(); } @Override - public void stop() { - try { - server.stop(); - } catch (Exception error) { - LOGGER.warn("Web server stop failed", error); - } + public void stop() throws Exception { + server.stop(); } } -- cgit v1.2.3 From b100cb211161d1014dfaa1ab532f1670c699e80d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 16:20:13 -0700 Subject: Improve web injection --- src/main/java/org/traccar/Main.java | 4 +- .../java/org/traccar/api/AsyncSocketServlet.java | 2 + src/main/java/org/traccar/api/MediaFilter.java | 47 +++++++++++++--------- .../java/org/traccar/api/ObjectMapperProvider.java | 13 +++--- src/main/java/org/traccar/web/WebModule.java | 29 +++++++++++++ src/main/java/org/traccar/web/WebServer.java | 25 +++++------- 6 files changed, 81 insertions(+), 39 deletions(-) create mode 100644 src/main/java/org/traccar/web/WebModule.java diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index e3286fd5e..bf69b565d 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -17,12 +17,12 @@ package org.traccar; import com.google.inject.Guice; import com.google.inject.Injector; -import com.google.inject.servlet.ServletModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; import org.traccar.schedule.ScheduleManager; import org.traccar.storage.DatabaseModule; +import org.traccar.web.WebModule; import org.traccar.web.WebServer; import java.io.File; @@ -115,7 +115,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new ServletModule()); + injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new WebModule()); Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 317ec469e..7c532179b 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -24,9 +24,11 @@ import org.traccar.config.Keys; import org.traccar.session.ConnectionManager; import javax.inject.Inject; +import javax.inject.Singleton; import javax.servlet.http.HttpSession; import java.time.Duration; +@Singleton public class AsyncSocketServlet extends JettyWebSocketServlet { private final ObjectMapper objectMapper; diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index e0609871a..6d95c66a8 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -16,19 +16,7 @@ */ package org.traccar.api; -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.traccar.Main; +import com.google.inject.Provider; import org.traccar.api.resource.SessionResource; import org.traccar.api.security.PermissionsService; import org.traccar.database.StatisticsManager; @@ -40,8 +28,35 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; + +@Singleton public class MediaFilter implements Filter { + private final Storage storage; + private final StatisticsManager statisticsManager; + private final Provider permissionsServiceProvider; + + @Inject + public MediaFilter( + Storage storage, StatisticsManager statisticsManager, + Provider permissionsServiceProvider) { + this.storage = storage; + this.statisticsManager = statisticsManager; + this.permissionsServiceProvider = permissionsServiceProvider; + } + @Override public void init(FilterConfig filterConfig) throws ServletException { } @@ -50,10 +65,6 @@ public class MediaFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - PermissionsService permissionsService = Main.getInjector().getInstance(PermissionsService.class); - Storage storage = Main.getInjector().getInstance(Storage.class); - StatisticsManager statisticsManager = Main.getInjector().getInstance(StatisticsManager.class); - HttpServletResponse httpResponse = (HttpServletResponse) response; try { HttpSession session = ((HttpServletRequest) request).getSession(false); @@ -75,7 +86,7 @@ public class MediaFilter implements Filter { Device device = storage.getObject(Device.class, new Request( new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", parts[1]))); if (device != null) { - permissionsService.checkPermission(Device.class, userId, device.getId()); + permissionsServiceProvider.get().checkPermission(Device.class, userId, device.getId()); chain.doFilter(request, response); return; } diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java index cb7adab6c..4d8b266fa 100644 --- a/src/main/java/org/traccar/api/ObjectMapperProvider.java +++ b/src/main/java/org/traccar/api/ObjectMapperProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,17 +16,20 @@ package org.traccar.api; import com.fasterxml.jackson.databind.ObjectMapper; -import org.traccar.Main; import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; -@Provider public class ObjectMapperProvider implements ContextResolver { + private final ObjectMapper objectMapper; + + public ObjectMapperProvider(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + @Override public ObjectMapper getContext(Class type) { - return Main.getInjector().getInstance(ObjectMapper.class); + return objectMapper; } } diff --git a/src/main/java/org/traccar/web/WebModule.java b/src/main/java/org/traccar/web/WebModule.java new file mode 100644 index 000000000..6c133ff74 --- /dev/null +++ b/src/main/java/org/traccar/web/WebModule.java @@ -0,0 +1,29 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.web; + +import com.google.inject.servlet.ServletModule; +import org.traccar.api.AsyncSocketServlet; +import org.traccar.api.MediaFilter; + +public class WebModule extends ServletModule { + + @Override + protected void configureServlets() { + filter("/api/media/*").through(MediaFilter.class); + serve("/api/socket").with(AsyncSocketServlet.class); + } +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 36f3d7682..46e401779 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -15,6 +15,7 @@ */ package org.traccar.web; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Injector; import com.google.inject.servlet.GuiceFilter; import org.eclipse.jetty.http.HttpCookie; @@ -40,13 +41,9 @@ import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerI import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; -import org.traccar.api.AsyncSocketServlet; import org.traccar.api.CorsResponseFilter; import org.traccar.api.DateParameterConverterProvider; -import org.traccar.api.MediaFilter; import org.traccar.api.ObjectMapperProvider; import org.traccar.api.ResourceErrorHandler; import org.traccar.api.resource.ServerResource; @@ -88,6 +85,8 @@ public class WebServer implements LifecycleObject { } ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + JettyWebSocketServletContainerInitializer.configure(servletHandler, null); + servletHandler.addFilter(GuiceFilter.class, "/*", EnumSet.allOf(DispatcherType.class)); initApi(servletHandler); initSessionConfig(servletHandler); @@ -140,7 +139,7 @@ public class WebServer implements LifecycleObject { } } }; - ServletHolder servletHolder = new ServletHolder(new AsyncProxyServlet.Transparent()); + ServletHolder servletHolder = new ServletHolder(AsyncProxyServlet.Transparent.class); servletHolder.setInitParameter("proxyTo", "http://localhost:" + port); servletHandler.addServlet(servletHolder, "/"); handlers.addHandler(servletHandler); @@ -164,11 +163,6 @@ public class WebServer implements LifecycleObject { } private void initApi(ServletContextHandler servletHandler) { - servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); - - servletHandler.addServlet(new ServletHolder(injector.getInstance(AsyncSocketServlet.class)), "/api/socket"); - JettyWebSocketServletContainerInitializer.configure(servletHandler, null); - String mediaPath = config.getString(Keys.MEDIA_PATH); if (mediaPath != null) { ServletHolder servletHolder = new ServletHolder(DefaultServlet.class); @@ -176,15 +170,18 @@ public class WebServer implements LifecycleObject { servletHolder.setInitParameter("dirAllowed", "false"); servletHolder.setInitParameter("pathInfoOnly", "true"); servletHandler.addServlet(servletHolder, "/api/media/*"); - servletHandler.addFilter(MediaFilter.class, "/api/media/*", EnumSet.allOf(DispatcherType.class)); } ResourceConfig resourceConfig = new ResourceConfig(); + resourceConfig.register(new GuiceBridgeInitializer(injector)); + resourceConfig.register(new ObjectMapperProvider(injector.getInstance(ObjectMapper.class))); resourceConfig.registerClasses( - JacksonFeature.class, ObjectMapperProvider.class, ResourceErrorHandler.class, - SecurityRequestFilter.class, CorsResponseFilter.class, DateParameterConverterProvider.class); + JacksonFeature.class, + DateParameterConverterProvider.class, + SecurityRequestFilter.class, + CorsResponseFilter.class, + ResourceErrorHandler.class); resourceConfig.packages(ServerResource.class.getPackage().getName()); - resourceConfig.register(new GuiceBridgeInitializer(injector)); servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } -- cgit v1.2.3 From 0de7889d5548ab16bc8dc31e8734dc48dd51d43d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 18:11:36 -0700 Subject: Better Jersey injection --- .../java/org/traccar/api/ObjectMapperProvider.java | 2 + .../api/security/SecurityRequestFilter.java | 19 +++++--- .../org/traccar/web/GuiceBridgeInitializer.java | 49 --------------------- .../traccar/web/WebInjectionManagerFactory.java | 50 ++++++++++++++++++++++ src/main/java/org/traccar/web/WebServer.java | 4 +- ....jersey.internal.inject.InjectionManagerFactory | 1 + 6 files changed, 67 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/org/traccar/web/GuiceBridgeInitializer.java create mode 100644 src/main/java/org/traccar/web/WebInjectionManagerFactory.java create mode 100644 src/main/resources/META-INF/services/org.glassfish.jersey.internal.inject.InjectionManagerFactory diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java index 4d8b266fa..d63a4b9b0 100644 --- a/src/main/java/org/traccar/api/ObjectMapperProvider.java +++ b/src/main/java/org/traccar/api/ObjectMapperProvider.java @@ -17,12 +17,14 @@ package org.traccar.api; import com.fasterxml.jackson.databind.ObjectMapper; +import javax.inject.Inject; import javax.ws.rs.ext.ContextResolver; public class ObjectMapperProvider implements ContextResolver { private final ObjectMapper objectMapper; + @Inject public ObjectMapperProvider(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index ad45dc112..3413175c8 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -17,7 +17,6 @@ package org.traccar.api.security; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; import org.traccar.api.resource.SessionResource; import org.traccar.database.LoginService; import org.traccar.database.StatisticsManager; @@ -26,11 +25,13 @@ import org.traccar.model.User; import org.traccar.storage.StorageException; import javax.annotation.security.PermitAll; +import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.WebApplicationException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ResourceInfo; +import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; import java.lang.reflect.Method; @@ -55,12 +56,18 @@ public class SecurityRequestFilter implements ContainerRequestFilter { return null; } - @javax.ws.rs.core.Context + @Context private HttpServletRequest request; - @javax.ws.rs.core.Context + @Context private ResourceInfo resourceInfo; + @Inject + private LoginService loginService; + + @Inject + private StatisticsManager statisticsManager; + @Override public void filter(ContainerRequestContext requestContext) { @@ -77,9 +84,9 @@ public class SecurityRequestFilter implements ContainerRequestFilter { try { String[] auth = decodeBasicAuth(authHeader); - User user = Main.getInjector().getInstance(LoginService.class).login(auth[0], auth[1]); + User user = loginService.login(auth[0], auth[1]); if (user != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(user.getId()); + statisticsManager.registerRequest(user.getId()); securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); } } catch (StorageException e) { @@ -90,7 +97,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { Long userId = (Long) request.getSession().getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); + statisticsManager.registerRequest(userId); securityContext = new UserSecurityContext(new UserPrincipal(userId)); } diff --git a/src/main/java/org/traccar/web/GuiceBridgeInitializer.java b/src/main/java/org/traccar/web/GuiceBridgeInitializer.java deleted file mode 100644 index fc9c88f3b..000000000 --- a/src/main/java/org/traccar/web/GuiceBridgeInitializer.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 Anton Tananaev (anton@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.web; - -import com.google.inject.Injector; -import org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager; -import org.glassfish.jersey.server.spi.Container; -import org.glassfish.jersey.server.spi.ContainerLifecycleListener; -import org.jvnet.hk2.guice.bridge.api.GuiceBridge; -import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; - -public class GuiceBridgeInitializer implements ContainerLifecycleListener { - - private final Injector injector; - - public GuiceBridgeInitializer(Injector injector) { - this.injector = injector; - } - - @Override - public void onStartup(Container container) { - var injectionManager = container.getApplicationHandler().getInjectionManager(); - var serviceLocator = ((ImmediateHk2InjectionManager) injectionManager).getServiceLocator(); - GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator); - var guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class); - guiceBridge.bridgeGuiceInjector(injector); - } - - @Override - public void onReload(Container container) { - } - - @Override - public void onShutdown(Container container) { - } -} diff --git a/src/main/java/org/traccar/web/WebInjectionManagerFactory.java b/src/main/java/org/traccar/web/WebInjectionManagerFactory.java new file mode 100644 index 000000000..14d9d3dbc --- /dev/null +++ b/src/main/java/org/traccar/web/WebInjectionManagerFactory.java @@ -0,0 +1,50 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.web; + +import org.glassfish.hk2.api.ServiceLocator; +import org.glassfish.jersey.inject.hk2.Hk2InjectionManagerFactory; +import org.glassfish.jersey.internal.inject.InjectionManager; +import org.glassfish.jersey.internal.inject.InjectionManagerFactory; +import org.jvnet.hk2.guice.bridge.api.GuiceBridge; +import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; +import org.traccar.Main; + +import javax.annotation.Priority; + +@Priority(20) +public class WebInjectionManagerFactory implements InjectionManagerFactory { + + private final InjectionManagerFactory originalFactory = new Hk2InjectionManagerFactory(); + + private InjectionManager injectGuiceBridge(InjectionManager injectionManager) { + var serviceLocator = injectionManager.getInstance(ServiceLocator.class); + GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator); + var guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class); + guiceBridge.bridgeGuiceInjector(Main.getInjector()); + return injectionManager; + } + + @Override + public InjectionManager create() { + return injectGuiceBridge(originalFactory.create()); + } + + @Override + public InjectionManager create(Object parent) { + return injectGuiceBridge(originalFactory.create(parent)); + } +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 46e401779..d7276d21f 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -15,7 +15,6 @@ */ package org.traccar.web; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Injector; import com.google.inject.servlet.GuiceFilter; import org.eclipse.jetty.http.HttpCookie; @@ -173,10 +172,9 @@ public class WebServer implements LifecycleObject { } ResourceConfig resourceConfig = new ResourceConfig(); - resourceConfig.register(new GuiceBridgeInitializer(injector)); - resourceConfig.register(new ObjectMapperProvider(injector.getInstance(ObjectMapper.class))); resourceConfig.registerClasses( JacksonFeature.class, + ObjectMapperProvider.class, DateParameterConverterProvider.class, SecurityRequestFilter.class, CorsResponseFilter.class, diff --git a/src/main/resources/META-INF/services/org.glassfish.jersey.internal.inject.InjectionManagerFactory b/src/main/resources/META-INF/services/org.glassfish.jersey.internal.inject.InjectionManagerFactory new file mode 100644 index 000000000..ce0a70630 --- /dev/null +++ b/src/main/resources/META-INF/services/org.glassfish.jersey.internal.inject.InjectionManagerFactory @@ -0,0 +1 @@ +org.traccar.web.WebInjectionManagerFactory -- cgit v1.2.3 From ee9abd94265eb704b5f5dd2262f1a3460bbe2a8f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 18:19:57 -0700 Subject: Refactor config usage --- src/main/java/org/traccar/MainModule.java | 6 +----- .../java/org/traccar/storage/DatabaseStorage.java | 21 +++++++++++++-------- src/main/java/org/traccar/storage/QueryBuilder.java | 17 ++++++++++------- src/main/java/org/traccar/web/ConsoleServlet.java | 16 +++++++++++----- src/main/java/org/traccar/web/WebServer.java | 2 +- 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index aac11e619..a29c2c910 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -88,6 +88,7 @@ public class MainModule extends AbstractModule { @Override protected void configure() { + bind(Storage.class).to(DatabaseStorage.class); bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); } @@ -108,11 +109,6 @@ public class MainModule extends AbstractModule { return Context.getConfig(); } - @Provides - public static Storage provideStorage(DataSource dataSource, ObjectMapper objectMapper) { - return new DatabaseStorage(dataSource, objectMapper); - } - @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 661e792d4..052f11ad2 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -16,6 +16,7 @@ package org.traccar.storage; import com.fasterxml.jackson.databind.ObjectMapper; +import org.traccar.config.Config; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; @@ -27,6 +28,7 @@ import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; +import javax.inject.Inject; import javax.sql.DataSource; import java.sql.SQLException; import java.util.HashMap; @@ -38,10 +40,13 @@ import java.util.stream.Collectors; public class DatabaseStorage extends Storage { + private final Config config; private final DataSource dataSource; private final ObjectMapper objectMapper; - public DatabaseStorage(DataSource dataSource, ObjectMapper objectMapper) { + @Inject + public DatabaseStorage(Config config, DataSource dataSource, ObjectMapper objectMapper) { + this.config = config; this.dataSource = dataSource; this.objectMapper = objectMapper; } @@ -55,7 +60,7 @@ public class DatabaseStorage extends Storage { query.append(formatOrder(request.getOrder())); query.append(formatLimit(request.getLimit())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -75,7 +80,7 @@ public class DatabaseStorage extends Storage { query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> ':' + c)); query.append(")"); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString(), true); builder.setObject(entity); return builder.executeUpdate(); } catch (SQLException e) { @@ -91,7 +96,7 @@ public class DatabaseStorage extends Storage { query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c + " = :" + c)); query.append(formatCondition(request.getCondition())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); builder.setObject(entity); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); @@ -108,7 +113,7 @@ public class DatabaseStorage extends Storage { query.append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -136,7 +141,7 @@ public class DatabaseStorage extends Storage { Condition combinedCondition = Condition.merge(conditions); query.append(formatCondition(combinedCondition)); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString()); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(combinedCondition).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -154,7 +159,7 @@ public class DatabaseStorage extends Storage { query.append(permission.get().keySet().stream().map(key -> ':' + key).collect(Collectors.joining(", "))); query.append(")"); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString(), true); for (var entry : permission.get().entrySet()) { builder.setLong(entry.getKey(), entry.getValue()); } @@ -172,7 +177,7 @@ public class DatabaseStorage extends Storage { query.append(permission .get().keySet().stream().map(key -> key + " = :" + key).collect(Collectors.joining(" AND "))); try { - QueryBuilder builder = QueryBuilder.create(dataSource, objectMapper, query.toString(), true); + QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString(), true); for (var entry : permission.get().entrySet()) { builder.setLong(entry.getKey(), entry.getValue()); } diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index 8502d5f0b..910ebf170 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Permission; @@ -42,10 +42,12 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +@SuppressWarnings("UnusedReturnValue") public final class QueryBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(QueryBuilder.class); + private final Config config; private final ObjectMapper objectMapper; private final Map> indexMap = new HashMap<>(); @@ -55,8 +57,9 @@ public final class QueryBuilder { private final boolean returnGeneratedKeys; private QueryBuilder( - DataSource dataSource, ObjectMapper objectMapper, + Config config, DataSource dataSource, ObjectMapper objectMapper, String query, boolean returnGeneratedKeys) throws SQLException { + this.config = config; this.objectMapper = objectMapper; this.query = query; this.returnGeneratedKeys = returnGeneratedKeys; @@ -133,14 +136,14 @@ public final class QueryBuilder { } public static QueryBuilder create( - DataSource dataSource, ObjectMapper objectMapper, String query) throws SQLException { - return new QueryBuilder(dataSource, objectMapper, query, false); + Config config, DataSource dataSource, ObjectMapper objectMapper, String query) throws SQLException { + return new QueryBuilder(config, dataSource, objectMapper, query, false); } public static QueryBuilder create( - DataSource dataSource, ObjectMapper objectMapper, String query, + Config config, DataSource dataSource, ObjectMapper objectMapper, String query, boolean returnGeneratedKeys) throws SQLException { - return new QueryBuilder(dataSource, objectMapper, query, returnGeneratedKeys); + return new QueryBuilder(config, dataSource, objectMapper, query, returnGeneratedKeys); } private List indexes(String name) { @@ -396,7 +399,7 @@ public final class QueryBuilder { } private void logQuery() { - if (Context.getConfig().getBoolean(Keys.LOGGER_QUERIES)) { + if (config.getBoolean(Keys.LOGGER_QUERIES)) { LOGGER.info(query); } } diff --git a/src/main/java/org/traccar/web/ConsoleServlet.java b/src/main/java/org/traccar/web/ConsoleServlet.java index 0f3dcd8fd..902a4f7a9 100644 --- a/src/main/java/org/traccar/web/ConsoleServlet.java +++ b/src/main/java/org/traccar/web/ConsoleServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import org.h2.server.web.ConnectionInfo; import org.h2.server.web.WebServlet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import java.lang.reflect.Field; @@ -30,6 +30,12 @@ public class ConsoleServlet extends WebServlet { private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleServlet.class); + private final Config config; + + public ConsoleServlet(Config config) { + this.config = config; + } + @Override public void init() { super.init(); @@ -40,9 +46,9 @@ public class ConsoleServlet extends WebServlet { org.h2.server.web.WebServer server = (org.h2.server.web.WebServer) field.get(this); ConnectionInfo connectionInfo = new ConnectionInfo("Traccar|" - + Context.getConfig().getString(Keys.DATABASE_DRIVER) + "|" - + Context.getConfig().getString(Keys.DATABASE_URL) + "|" - + Context.getConfig().getString(Keys.DATABASE_USER)); + + config.getString(Keys.DATABASE_DRIVER) + "|" + + config.getString(Keys.DATABASE_URL) + "|" + + config.getString(Keys.DATABASE_USER)); Method method; diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index d7276d21f..6c8a798b4 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -91,7 +91,7 @@ public class WebServer implements LifecycleObject { initSessionConfig(servletHandler); if (config.getBoolean(Keys.WEB_CONSOLE)) { - servletHandler.addServlet(new ServletHolder(new ConsoleServlet()), "/console/*"); + servletHandler.addServlet(new ServletHolder(new ConsoleServlet(config)), "/console/*"); } initWebApp(servletHandler); -- cgit v1.2.3 From 15c4b6b21a31c63bc0f7e624e26d032d531c459d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 18:48:08 -0700 Subject: Refactor geofence classes --- src/main/java/org/traccar/MainModule.java | 1 - .../java/org/traccar/geofence/GeofenceCircle.java | 4 +- .../org/traccar/geofence/GeofenceGeometry.java | 5 ++- .../java/org/traccar/geofence/GeofencePolygon.java | 4 +- .../org/traccar/geofence/GeofencePolyline.java | 23 +++++------ .../handler/events/GeofenceEventHandler.java | 7 +++- .../org/traccar/helper/model/GeofenceUtil.java | 6 ++- src/main/java/org/traccar/model/Geofence.java | 22 ++++------- .../org/traccar/session/cache/CacheManager.java | 7 +++- .../org/traccar/geofence/GeofenceCircleTest.java | 13 +++--- .../org/traccar/geofence/GeofencePolygonTest.java | 37 +++++++---------- .../org/traccar/geofence/GeofencePolylineTest.java | 46 ++++++++++++++-------- 12 files changed, 93 insertions(+), 82 deletions(-) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a29c2c910..a9337a3a2 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -75,7 +75,6 @@ import org.traccar.web.WebServer; import javax.annotation.Nullable; import javax.inject.Singleton; -import javax.sql.DataSource; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.ext.ContextResolver; diff --git a/src/main/java/org/traccar/geofence/GeofenceCircle.java b/src/main/java/org/traccar/geofence/GeofenceCircle.java index 5d566f84e..59feb1730 100644 --- a/src/main/java/org/traccar/geofence/GeofenceCircle.java +++ b/src/main/java/org/traccar/geofence/GeofenceCircle.java @@ -18,7 +18,9 @@ package org.traccar.geofence; import java.text.DecimalFormat; import java.text.ParseException; +import org.traccar.config.Config; import org.traccar.helper.DistanceCalculator; +import org.traccar.model.Geofence; public class GeofenceCircle extends GeofenceGeometry { @@ -44,7 +46,7 @@ public class GeofenceCircle extends GeofenceGeometry { } @Override - public boolean containsPoint(double latitude, double longitude) { + public boolean containsPoint(Config config, Geofence geofence, double latitude, double longitude) { return distanceFromCenter(latitude, longitude) <= radius; } diff --git a/src/main/java/org/traccar/geofence/GeofenceGeometry.java b/src/main/java/org/traccar/geofence/GeofenceGeometry.java index 2c45c22af..fadabab1c 100644 --- a/src/main/java/org/traccar/geofence/GeofenceGeometry.java +++ b/src/main/java/org/traccar/geofence/GeofenceGeometry.java @@ -15,11 +15,14 @@ */ package org.traccar.geofence; +import org.traccar.config.Config; +import org.traccar.model.Geofence; + import java.text.ParseException; public abstract class GeofenceGeometry { - public abstract boolean containsPoint(double latitude, double longitude); + public abstract boolean containsPoint(Config config, Geofence geofence, double latitude, double longitude); public abstract double calculateArea(); diff --git a/src/main/java/org/traccar/geofence/GeofencePolygon.java b/src/main/java/org/traccar/geofence/GeofencePolygon.java index cd2cbf16a..13f6658ef 100644 --- a/src/main/java/org/traccar/geofence/GeofencePolygon.java +++ b/src/main/java/org/traccar/geofence/GeofencePolygon.java @@ -19,6 +19,8 @@ import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.context.jts.JtsSpatialContextFactory; import org.locationtech.spatial4j.shape.ShapeFactory; import org.locationtech.spatial4j.shape.jts.JtsShapeFactory; +import org.traccar.config.Config; +import org.traccar.model.Geofence; import java.text.ParseException; import java.util.ArrayList; @@ -95,7 +97,7 @@ public class GeofencePolygon extends GeofenceGeometry { } @Override - public boolean containsPoint(double latitude, double longitude) { + public boolean containsPoint(Config config, Geofence geofence, double latitude, double longitude) { int polyCorners = coordinates.size(); int i; diff --git a/src/main/java/org/traccar/geofence/GeofencePolyline.java b/src/main/java/org/traccar/geofence/GeofencePolyline.java index 370bf99bb..d9c280ae4 100644 --- a/src/main/java/org/traccar/geofence/GeofencePolyline.java +++ b/src/main/java/org/traccar/geofence/GeofencePolyline.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,23 +19,28 @@ package org.traccar.geofence; import java.text.ParseException; import java.util.ArrayList; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.DistanceCalculator; +import org.traccar.model.Geofence; public class GeofencePolyline extends GeofenceGeometry { private ArrayList coordinates; - private double distance; public GeofencePolyline() { } - public GeofencePolyline(String wkt, double distance) throws ParseException { + public GeofencePolyline(String wkt) throws ParseException { fromWkt(wkt); - this.distance = distance; } @Override - public boolean containsPoint(double latitude, double longitude) { + public boolean containsPoint(Config config, Geofence geofence, double latitude, double longitude) { + double distance = geofence.getDouble("polylineDistance"); + if (distance == 0) { + distance = config.getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE); + } for (int i = 1; i < coordinates.size(); i++) { if (DistanceCalculator.distanceToLine( latitude, longitude, coordinates.get(i - 1).getLat(), coordinates.get(i - 1).getLon(), @@ -56,9 +61,9 @@ public class GeofencePolyline extends GeofenceGeometry { StringBuilder buf = new StringBuilder(); buf.append("LINESTRING ("); for (Coordinate coordinate : coordinates) { - buf.append(String.valueOf(coordinate.getLat())); + buf.append(coordinate.getLat()); buf.append(" "); - buf.append(String.valueOf(coordinate.getLon())); + buf.append(coordinate.getLon()); buf.append(", "); } return buf.substring(0, buf.length() - 2) + ")"; @@ -105,8 +110,4 @@ public class GeofencePolyline extends GeofenceGeometry { } - public void setDistance(double distance) { - this.distance = distance; - } - } diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 724f8f0d0..0a924cfc3 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -16,6 +16,7 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; +import org.traccar.config.Config; import org.traccar.helper.model.GeofenceUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Calendar; @@ -35,11 +36,13 @@ import java.util.Map; @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { + private final Config config; private final CacheManager cacheManager; private final ConnectionManager connectionManager; @Inject - public GeofenceEventHandler(CacheManager cacheManager, ConnectionManager connectionManager) { + public GeofenceEventHandler(Config config, CacheManager cacheManager, ConnectionManager connectionManager) { + this.config = config; this.cacheManager = cacheManager; this.connectionManager = connectionManager; } @@ -54,7 +57,7 @@ public class GeofenceEventHandler extends BaseEventHandler { return null; } - List currentGeofences = GeofenceUtil.getCurrentGeofences(cacheManager, position); + List currentGeofences = GeofenceUtil.getCurrentGeofences(config, cacheManager, position); List oldGeofences = new ArrayList<>(); if (device.getGeofenceIds() != null) { oldGeofences.addAll(device.getGeofenceIds()); diff --git a/src/main/java/org/traccar/helper/model/GeofenceUtil.java b/src/main/java/org/traccar/helper/model/GeofenceUtil.java index f56bf4224..9f063a8b4 100644 --- a/src/main/java/org/traccar/helper/model/GeofenceUtil.java +++ b/src/main/java/org/traccar/helper/model/GeofenceUtil.java @@ -15,6 +15,7 @@ */ package org.traccar.helper.model; +import org.traccar.config.Config; import org.traccar.model.Geofence; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; @@ -27,10 +28,11 @@ public final class GeofenceUtil { private GeofenceUtil() { } - public static List getCurrentGeofences(CacheManager cacheManager, Position position) { + public static List getCurrentGeofences(Config config, CacheManager cacheManager, Position position) { List result = new ArrayList<>(); for (Geofence geofence : cacheManager.getDeviceObjects(position.getDeviceId(), Geofence.class)) { - if (geofence.getGeometry().containsPoint(position.getLatitude(), position.getLongitude())) { + if (geofence.getGeometry().containsPoint( + config, geofence, position.getLatitude(), position.getLongitude())) { result.add(geofence.getId()); } } diff --git a/src/main/java/org/traccar/model/Geofence.java b/src/main/java/org/traccar/model/Geofence.java index 5b857580d..9259028fb 100644 --- a/src/main/java/org/traccar/model/Geofence.java +++ b/src/main/java/org/traccar/model/Geofence.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,26 +15,19 @@ */ package org.traccar.model; -import java.text.ParseException; - -import org.traccar.Context; -import org.traccar.config.Keys; -import org.traccar.storage.QueryIgnore; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.traccar.geofence.GeofenceCircle; import org.traccar.geofence.GeofenceGeometry; import org.traccar.geofence.GeofencePolygon; import org.traccar.geofence.GeofencePolyline; - -import com.fasterxml.jackson.annotation.JsonIgnore; +import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; +import java.text.ParseException; + @StorageName("tc_geofences") public class Geofence extends ScheduledModel { - public static final String TYPE_GEOFENCE_CILCLE = "geofenceCircle"; - public static final String TYPE_GEOFENCE_POLYGON = "geofencePolygon"; - public static final String TYPE_GEOFENCE_POLYLINE = "geofencePolyline"; - private String name; public String getName() { @@ -68,9 +61,7 @@ public class Geofence extends ScheduledModel { } else if (area.startsWith("POLYGON")) { geometry = new GeofencePolygon(area); } else if (area.startsWith("LINESTRING")) { - final double distance = getDouble("polylineDistance"); - geometry = new GeofencePolyline(area, distance > 0 ? distance - : Context.getConfig().getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE)); + geometry = new GeofencePolyline(area); } else { throw new ParseException("Unknown geometry type", 0); } @@ -92,4 +83,5 @@ public class Geofence extends ScheduledModel { area = geometry.toWkt(); this.geometry = geometry; } + } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 18daeae15..14034f3d6 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -15,6 +15,7 @@ */ package org.traccar.session.cache; +import org.traccar.config.Config; import org.traccar.helper.model.GeofenceUtil; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; @@ -53,6 +54,7 @@ public class CacheManager { private static final Collection> CLASSES = Arrays.asList( Attribute.class, Driver.class, Geofence.class, Maintenance.class, Notification.class); + private final Config config; private final Storage storage; private final ReadWriteLock lock = new ReentrantReadWriteLock(); @@ -65,7 +67,8 @@ public class CacheManager { private final Map> notificationUsers = new HashMap<>(); @Inject - public CacheManager(Storage storage) throws StorageException { + public CacheManager(Config config, Storage storage) throws StorageException { + this.config = config; this.storage = storage; invalidateServer(); invalidateUsers(); @@ -315,7 +318,7 @@ public class CacheManager { private void invalidateDeviceGeofences(Device device) { Position position = getPosition(device.getId()); if (position != null) { - device.setGeofenceIds(GeofenceUtil.getCurrentGeofences(this, position)); + device.setGeofenceIds(GeofenceUtil.getCurrentGeofences(config, this, position)); } } diff --git a/src/test/java/org/traccar/geofence/GeofenceCircleTest.java b/src/test/java/org/traccar/geofence/GeofenceCircleTest.java index 038e4b6d6..9a02cec76 100644 --- a/src/test/java/org/traccar/geofence/GeofenceCircleTest.java +++ b/src/test/java/org/traccar/geofence/GeofenceCircleTest.java @@ -5,6 +5,7 @@ import org.junit.Test; import java.text.ParseException; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class GeofenceCircleTest { @@ -12,17 +13,15 @@ public class GeofenceCircleTest { @Test public void testCircleWkt() throws ParseException { String test = "CIRCLE (55.75414 37.6204, 100)"; - GeofenceGeometry geofenceGeometry = new GeofenceCircle(); - geofenceGeometry.fromWkt(test); + GeofenceGeometry geofenceGeometry = new GeofenceCircle(test); assertEquals(geofenceGeometry.toWkt(), test); } @Test public void testContainsCircle() throws ParseException { - String test = "CIRCLE (55.75414 37.6204, 100)"; - GeofenceGeometry geofenceGeometry = new GeofenceCircle(); - geofenceGeometry.fromWkt(test); - assertTrue(geofenceGeometry.containsPoint(55.75477, 37.62025)); - assertTrue(!geofenceGeometry.containsPoint(55.75545, 37.61921)); + GeofenceGeometry geofenceGeometry = new GeofenceCircle("CIRCLE (55.75414 37.6204, 100)"); + assertTrue(geofenceGeometry.containsPoint(null, null, 55.75477, 37.62025)); + assertFalse(geofenceGeometry.containsPoint(null, null, 55.75545, 37.61921)); } + } diff --git a/src/test/java/org/traccar/geofence/GeofencePolygonTest.java b/src/test/java/org/traccar/geofence/GeofencePolygonTest.java index 1b8de68ad..5baecd771 100644 --- a/src/test/java/org/traccar/geofence/GeofencePolygonTest.java +++ b/src/test/java/org/traccar/geofence/GeofencePolygonTest.java @@ -19,41 +19,34 @@ public class GeofencePolygonTest { @Test public void testPolygonWkt() throws ParseException { String test = "POLYGON ((55.75474 37.61823, 55.75513 37.61888, 55.7535 37.6222, 55.75315 37.62165))"; - GeofenceGeometry geofenceGeometry = new GeofencePolygon(); - geofenceGeometry.fromWkt(test); + GeofenceGeometry geofenceGeometry = new GeofencePolygon(test); assertEquals(geofenceGeometry.toWkt(), test); } @Test public void testContainsPolygon() throws ParseException { - String test = "POLYGON ((55.75474 37.61823, 55.75513 37.61888, 55.7535 37.6222, 55.75315 37.62165))"; - GeofenceGeometry geofenceGeometry = new GeofencePolygon(); - geofenceGeometry.fromWkt(test); - assertTrue(geofenceGeometry.containsPoint(55.75476, 37.61915)); - assertFalse(geofenceGeometry.containsPoint(55.75545, 37.61921)); - + GeofenceGeometry geofenceGeometry = new GeofencePolygon( + "POLYGON ((55.75474 37.61823, 55.75513 37.61888, 55.7535 37.6222, 55.75315 37.62165))"); + assertTrue(geofenceGeometry.containsPoint(null, null, 55.75476, 37.61915)); + assertFalse(geofenceGeometry.containsPoint(null, null, 55.75545, 37.61921)); } @Test public void testContainsPolygon180() throws ParseException { - String test = "POLYGON ((66.9494 179.838, 66.9508 -179.8496, 66.8406 -180.0014))"; - GeofenceGeometry geofenceGeometry = new GeofencePolygon(); - geofenceGeometry.fromWkt(test); - assertTrue(geofenceGeometry.containsPoint(66.9015, -180.0096)); - assertTrue(geofenceGeometry.containsPoint(66.9015, 179.991)); - assertFalse(geofenceGeometry.containsPoint(66.8368, -179.8792)); - + GeofenceGeometry geofenceGeometry = new GeofencePolygon( + "POLYGON ((66.9494 179.838, 66.9508 -179.8496, 66.8406 -180.0014))"); + assertTrue(geofenceGeometry.containsPoint(null, null, 66.9015, -180.0096)); + assertTrue(geofenceGeometry.containsPoint(null, null, 66.9015, 179.991)); + assertFalse(geofenceGeometry.containsPoint(null, null, 66.8368, -179.8792)); } @Test public void testContainsPolygon0() throws ParseException { - String test = "POLYGON ((51.1966 -0.6207, 51.1897 0.4147, 50.9377 0.5136, 50.8675 -0.6082))"; - GeofenceGeometry geofenceGeometry = new GeofencePolygon(); - geofenceGeometry.fromWkt(test); - assertTrue(geofenceGeometry.containsPoint(51.0466, -0.0165)); - assertTrue(geofenceGeometry.containsPoint(51.0466, 0.018)); - assertFalse(geofenceGeometry.containsPoint(50.9477, 0.5836)); - + GeofenceGeometry geofenceGeometry = new GeofencePolygon( + "POLYGON ((51.1966 -0.6207, 51.1897 0.4147, 50.9377 0.5136, 50.8675 -0.6082))"); + assertTrue(geofenceGeometry.containsPoint(null, null, 51.0466, -0.0165)); + assertTrue(geofenceGeometry.containsPoint(null, null, 51.0466, 0.018)); + assertFalse(geofenceGeometry.containsPoint(null, null, 50.9477, 0.5836)); } } diff --git a/src/test/java/org/traccar/geofence/GeofencePolylineTest.java b/src/test/java/org/traccar/geofence/GeofencePolylineTest.java index 0e8905319..b7ee14510 100644 --- a/src/test/java/org/traccar/geofence/GeofencePolylineTest.java +++ b/src/test/java/org/traccar/geofence/GeofencePolylineTest.java @@ -1,47 +1,59 @@ package org.traccar.geofence; import org.junit.Test; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.Geofence; import java.text.ParseException; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class GeofencePolylineTest { @Test public void testPolylineWkt() throws ParseException { String test = "LINESTRING (55.75474 37.61823, 55.75513 37.61888, 55.7535 37.6222, 55.75315 37.62165)"; - GeofenceGeometry geofenceGeometry = new GeofencePolyline(); - geofenceGeometry.fromWkt(test); + GeofenceGeometry geofenceGeometry = new GeofencePolyline(test); assertEquals(geofenceGeometry.toWkt(), test); } @Test public void testContainsPolyline1Interval() throws ParseException { - String test = "LINESTRING (56.83777 60.59833, 56.83766 60.5968)"; - GeofenceGeometry geofenceGeometry = new GeofencePolyline(test, 35); - assertTrue(geofenceGeometry.containsPoint(56.83801, 60.59748)); - ((GeofencePolyline) geofenceGeometry).setDistance(15); - assertTrue(!geofenceGeometry.containsPoint(56.83801, 60.59748)); + GeofenceGeometry geofenceGeometry = new GeofencePolyline( + "LINESTRING (56.83777 60.59833, 56.83766 60.5968)"); + Config config = mock(Config.class); + when(config.getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE)).thenReturn(35.0); + assertTrue(geofenceGeometry.containsPoint(config, mock(Geofence.class), 56.83801, 60.59748)); + when(config.getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE)).thenReturn(15.0); + assertFalse(geofenceGeometry.containsPoint(config, mock(Geofence.class), 56.83801, 60.59748)); } @Test public void testContainsPolyline3Intervals() throws ParseException { - String test = "LINESTRING (56.836 60.6126, 56.8393 60.6114, 56.83887 60.60811, 56.83782 60.5988)"; - GeofenceGeometry geofenceGeometry = new GeofencePolyline(test, 15); - assertTrue(geofenceGeometry.containsPoint(56.83847, 60.60458)); - assertTrue(!geofenceGeometry.containsPoint(56.83764, 60.59725)); - assertTrue(!geofenceGeometry.containsPoint(56.83861, 60.60822)); + GeofenceGeometry geofenceGeometry = new GeofencePolyline( + "LINESTRING (56.836 60.6126, 56.8393 60.6114, 56.83887 60.60811, 56.83782 60.5988)"); + Config config = mock(Config.class); + when(config.getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE)).thenReturn(15.0); + assertTrue(geofenceGeometry.containsPoint(config, mock(Geofence.class), 56.83847, 60.60458)); + assertFalse(geofenceGeometry.containsPoint(config, mock(Geofence.class), 56.83764, 60.59725)); + assertFalse(geofenceGeometry.containsPoint(config, mock(Geofence.class), 56.83861, 60.60822)); } @Test public void testContainsPolylineNear180() throws ParseException { - String test = "LINESTRING (66.9494 179.838, 66.9508 -179.8496)"; - GeofenceGeometry geofenceGeometry = new GeofencePolyline(test, 25); - assertTrue(geofenceGeometry.containsPoint(66.95, 180.0)); - assertTrue(!geofenceGeometry.containsPoint(66.96, 180.0)); - assertTrue(!geofenceGeometry.containsPoint(66.9509, -179.83)); + GeofenceGeometry geofenceGeometry = new GeofencePolyline( + "LINESTRING (66.9494 179.838, 66.9508 -179.8496)"); + Config config = mock(Config.class); + when(config.getDouble(Keys.GEOFENCE_POLYLINE_DISTANCE)).thenReturn(25.0); + assertTrue(geofenceGeometry.containsPoint(config, mock(Geofence.class), 66.95, 180.0)); + assertFalse(geofenceGeometry.containsPoint(config, mock(Geofence.class), 66.96, 180.0)); + assertFalse(geofenceGeometry.containsPoint(config, mock(Geofence.class), 66.9509, -179.83)); } + } -- cgit v1.2.3 From 316ef36ca8bf6425df5a6186da2e7901dcb23c0e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 17 Jun 2022 17:20:11 -0700 Subject: Fix caching issues --- src/main/java/org/traccar/session/ConnectionManager.java | 2 +- src/main/java/org/traccar/session/cache/CacheManager.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index c8c07f9c7..6d5fefa75 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -128,7 +128,7 @@ public class ConnectionManager { if (oldSession != null) { Endpoint oldEndpoint = new Endpoint(oldSession.getChannel(), oldSession.getRemoteAddress()); Map oldEndpointSessions = sessionsByEndpoint.get(oldEndpoint); - if (oldEndpointSessions.size() > 1) { + if (oldEndpointSessions != null && oldEndpointSessions.size() > 1) { oldEndpointSessions.remove(device.getUniqueId()); } else { sessionsByEndpoint.remove(oldEndpoint); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 14034f3d6..896df83e7 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -245,6 +245,7 @@ public class CacheManager { new Columns.All(), new Condition.Permission(User.class, Device.class, deviceId))); links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toList())); for (var user : users) { + addObject(deviceId, user); var notifications = storage.getObjects(Notification.class, new Request( new Columns.All(), new Condition.Permission(User.class, user.getId(), Notification.class))); notifications.stream() -- cgit v1.2.3 From 9fa2fc7091041a5cffa9092318d5d2f5a1a367a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 07:35:32 -0700 Subject: Migrate device resource --- .../org/traccar/api/resource/DeviceResource.java | 101 ++++++++++++++------- .../java/org/traccar/database/DeviceManager.java | 43 +++------ .../org/traccar/database/PermissionsManager.java | 11 --- 3 files changed, 80 insertions(+), 75 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index cd5ebf0c5..2509c9003 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,18 @@ */ package org.traccar.api.resource; -import org.traccar.Context; +import org.traccar.Main; import org.traccar.api.BaseObjectResource; -import org.traccar.database.DeviceManager; import org.traccar.helper.LogAction; import org.traccar.model.Device; import org.traccar.model.DeviceAccumulators; +import org.traccar.model.Position; +import org.traccar.model.User; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -32,9 +37,8 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.Collection; -import java.util.HashSet; +import java.util.LinkedList; import java.util.List; -import java.util.Set; @Path("devices") @Produces(MediaType.APPLICATION_JSON) @@ -50,38 +54,46 @@ public class DeviceResource extends BaseObjectResource { @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("uniqueId") List uniqueIds, @QueryParam("id") List deviceIds) throws StorageException { - DeviceManager deviceManager = Context.getDeviceManager(); - Set result; - if (all) { - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - result = deviceManager.getAllItems(); - } else { - Context.getPermissionsManager().checkManager(getUserId()); - result = deviceManager.getUserItems(getUserId()); - } - } else if (uniqueIds.isEmpty() && deviceIds.isEmpty()) { - if (userId == 0) { - userId = getUserId(); - } - permissionsService.checkUser(getUserId(), userId); - if (Context.getPermissionsManager().getUserAdmin(getUserId())) { - result = deviceManager.getAllUserItems(userId); - } else { - result = deviceManager.getUserItems(userId); - } - } else { - result = new HashSet<>(); + + if (!uniqueIds.isEmpty() || !deviceIds.isEmpty()) { + + List result = new LinkedList<>(); for (String uniqueId : uniqueIds) { - Device device = deviceManager.getByUniqueId(uniqueId); - permissionsService.checkPermission(Device.class, getUserId(), device.getId()); - result.add(device.getId()); + result.addAll(storage.getObjects(Device.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("uniqueId", "uniqueId", uniqueId), + new Condition.Permission(User.class, getUserId(), Device.class))))); } for (Long deviceId : deviceIds) { - permissionsService.checkPermission(Device.class, getUserId(), deviceId); - result.add(deviceId); + result.addAll(storage.getObjects(Device.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("id", "id", deviceId), + new Condition.Permission(User.class, getUserId(), Device.class))))); + } + return result; + + } else { + + var conditions = new LinkedList(); + + if (all) { + if (permissionsService.notAdmin(getUserId())) { + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); + } + } else { + if (userId == 0) { + conditions.add(new Condition.Permission(User.class, getUserId(), baseClass)); + } else { + permissionsService.checkUser(getUserId(), userId); + conditions.add(new Condition.Permission(User.class, userId, baseClass).excludeGroups()); + } } + + return storage.getObjects(baseClass, new Request(new Columns.All(), Condition.merge(conditions))); + } - return deviceManager.getItems(result); } @Path("{id}/accumulators") @@ -91,7 +103,30 @@ public class DeviceResource extends BaseObjectResource { permissionsService.checkManager(getUserId()); permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); } - Context.getDeviceManager().resetDeviceAccumulators(entity); + + Position position = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.LatestPositions(entity.getDeviceId()))); + if (position != null) { + if (entity.getTotalDistance() != null) { + position.getAttributes().put(Position.KEY_TOTAL_DISTANCE, entity.getTotalDistance()); + } + if (entity.getHours() != null) { + position.getAttributes().put(Position.KEY_HOURS, entity.getHours()); + } + position.setId(storage.addObject(position, new Request(new Columns.Exclude("id")))); + + Device device = new Device(); + device.setId(position.getDeviceId()); + device.setPositionId(position.getId()); + storage.updateObject(device, new Request( + new Columns.Include("positionId"), + new Condition.Equals("id", "id"))); + + Main.getInjector().getInstance(CacheManager.class).updatePosition(position); + } else { + throw new IllegalArgumentException(); + } + LogAction.resetDeviceAccumulators(getUserId(), entity.getDeviceId()); return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index bd100245c..81043fd7a 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -15,32 +15,30 @@ */ package org.traccar.database; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; -import org.traccar.config.Config; import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; import org.traccar.model.Device; -import org.traccar.session.ConnectionManager; -import org.traccar.session.DeviceState; -import org.traccar.model.DeviceAccumulators; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; +import org.traccar.session.ConnectionManager; +import org.traccar.session.DeviceState; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + public class DeviceManager extends BaseObjectManager implements IdentityManager { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); @@ -378,23 +376,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return result; } - public void resetDeviceAccumulators(DeviceAccumulators deviceAccumulators) throws StorageException { - Position last = positions.get(deviceAccumulators.getDeviceId()); - if (last != null) { - if (deviceAccumulators.getTotalDistance() != null) { - last.getAttributes().put(Position.KEY_TOTAL_DISTANCE, deviceAccumulators.getTotalDistance()); - } - if (deviceAccumulators.getHours() != null) { - last.getAttributes().put(Position.KEY_HOURS, deviceAccumulators.getHours()); - } - getDataManager().addObject(last); - updateLatestPosition(last); - Main.getInjector().getInstance(CacheManager.class).updatePosition(last); - } else { - throw new IllegalArgumentException(); - } - } - public DeviceState getDeviceState(long deviceId) { DeviceState deviceState = deviceStates.get(deviceId); if (deviceState == null) { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 4ac27c717..9d1e5aadf 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -179,17 +179,6 @@ public class PermissionsManager { return user != null && user.getAdministrator(); } - public boolean getUserManager(long userId) { - User user = getUser(userId); - return user != null && user.getUserLimit() != 0; - } - - public void checkManager(long userId) throws SecurityException { - if (!getUserManager(userId)) { - throw new SecurityException("Manager access required"); - } - } - public void refreshPermissions(Permission permission) { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) -- cgit v1.2.3 From 68826cdc767bae6b8b39e88667372f0c6161efa9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 07:40:47 -0700 Subject: Rename key type --- src/main/java/org/traccar/config/KeyType.java | 2 +- src/main/java/org/traccar/config/Keys.java | 348 +++++++++++++------------- 2 files changed, 175 insertions(+), 175 deletions(-) diff --git a/src/main/java/org/traccar/config/KeyType.java b/src/main/java/org/traccar/config/KeyType.java index 57a95c9ec..46628f9fc 100644 --- a/src/main/java/org/traccar/config/KeyType.java +++ b/src/main/java/org/traccar/config/KeyType.java @@ -16,7 +16,7 @@ package org.traccar.config; public enum KeyType { - GLOBAL, + CONFIG, SERVER, USER, DEVICE, diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 82afe048b..292202de0 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -27,7 +27,7 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_ADDRESS = new ConfigSuffix<>( ".address", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Port number for the protocol. Most protocols use TCP on the transport layer. Some protocols use UDP. Some @@ -35,7 +35,7 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_PORT = new ConfigSuffix<>( ".port", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * List of devices for polling protocols. List should contain unique ids separated by commas. Used only for polling @@ -43,21 +43,21 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_DEVICES = new ConfigSuffix<>( ".devices", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Polling interval in seconds. Used only for polling protocols. */ public static final ConfigSuffix PROTOCOL_INTERVAL = new ConfigSuffix<>( ".interval", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable SSL support for the protocol. Not all protocols support this. */ public static final ConfigSuffix PROTOCOL_SSL = new ConfigSuffix<>( ".ssl", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Connection timeout value in seconds. Because sometimes there is no way to detect lost TCP connection old @@ -67,28 +67,28 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_TIMEOUT = new ConfigSuffix<>( ".timeout", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Device password. Commonly used in some protocol for sending commands. */ public static final ConfigSuffix PROTOCOL_DEVICE_PASSWORD = new ConfigSuffix<>( ".devicePassword", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Default protocol mask to use. Currently used only by Skypatrol protocol. */ public static final ConfigSuffix PROTOCOL_MASK = new ConfigSuffix<>( ".mask", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Custom message length. Currently used only by H2 protocol for specifying binary message length. */ public static final ConfigSuffix PROTOCOL_MESSAGE_LENGTH = new ConfigSuffix<>( ".messageLength", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable extended functionality for the protocol. The reason it's disabled by default is that not all devices @@ -96,28 +96,28 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_EXTENDED = new ConfigSuffix<>( ".extended", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Decode string as UTF8 instead of ASCII. Only applicable for some protocols. */ public static final ConfigSuffix PROTOCOL_UTF8 = new ConfigSuffix<>( ".utf8", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable CAN decoding for the protocol. Similar to 'extended' configuration, it's not supported for some devices. */ public static final ConfigSuffix PROTOCOL_CAN = new ConfigSuffix<>( ".can", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Indicates whether server acknowledgement is required. Only applicable for some protocols. */ public static final ConfigSuffix PROTOCOL_ACK = new ConfigSuffix<>( ".ack", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Ignore device reported fix time. Useful in case some devices report invalid time. Currently only available for @@ -125,91 +125,91 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_IGNORE_FIX_TIME = new ConfigSuffix<>( ".ignoreFixTime", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Decode additional TK103 attributes. Not supported for some devices. */ public static final ConfigSuffix PROTOCOL_DECODE_LOW = new ConfigSuffix<>( ".decodeLow", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Use long date format for Atrack protocol. */ public static final ConfigSuffix PROTOCOL_LONG_DATE = new ConfigSuffix<>( ".longDate", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Use decimal fuel value format for Atrack protocol. */ public static final ConfigSuffix PROTOCOL_DECIMAL_FUEL = new ConfigSuffix<>( ".decimalFuel", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Indicates additional custom attributes for Atrack protocol. */ public static final ConfigSuffix PROTOCOL_CUSTOM = new ConfigSuffix<>( ".custom", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Custom format string for Atrack protocol. */ public static final ConfigSuffix PROTOCOL_FORM = new ConfigSuffix<>( ".form", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Protocol configuration. Required for some devices for decoding incoming data. */ public static final ConfigSuffix PROTOCOL_CONFIG = new ConfigSuffix<>( ".config", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Alarm mapping for Atrack protocol. */ public static final ConfigSuffix PROTOCOL_ALARM_MAP = new ConfigSuffix<>( ".alarmMap", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Indicates whether TAIP protocol should have prefixes for messages. */ public static final ConfigSuffix PROTOCOL_PREFIX = new ConfigSuffix<>( ".prefix", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Some devices require server address confirmation. Use this parameter to configure correct public address. */ public static final ConfigSuffix PROTOCOL_SERVER = new ConfigSuffix<>( ".server", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * ORBCOMM API access id. */ public static final ConfigKey ORBCOMM_ACCESS_ID = new ConfigKey<>( "orbcomm.accessId", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * ORBCOMM API password. */ public static final ConfigKey ORBCOMM_PASSWORD = new ConfigKey<>( "orbcomm.password", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Server wide connection timeout value in seconds. See protocol timeout for more information. */ public static final ConfigKey SERVER_TIMEOUT = new ConfigKey<>( "server.timeout", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Address for uploading aggregated anonymous usage statistics. Uploaded information is the same you can see on the @@ -217,63 +217,63 @@ public final class Keys { */ public static final ConfigKey SERVER_STATISTICS = new ConfigKey<>( "server.statistics", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * If true, the event is generated once at the beginning of overspeeding period. */ public static final ConfigKey EVENT_OVERSPEED_NOT_REPEAT = new ConfigKey<>( "event.overspeed.notRepeat", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Minimal over speed duration to trigger the event. Value in seconds. */ public static final ConfigKey EVENT_OVERSPEED_MINIMAL_DURATION = new ConfigKey<>( "event.overspeed.minimalDuration", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Relevant only for geofence speed limits. Use the lowest speed limit from all geofences. */ public static final ConfigKey EVENT_OVERSPEED_PREFER_LOWEST = new ConfigKey<>( "event.overspeed.preferLowest", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Driver behavior acceleration threshold. Value is in meter per second squared. */ public static final ConfigKey EVENT_BEHAVIOR_ACCELERATION_THRESHOLD = new ConfigKey<>( "event.behavior.accelerationThreshold", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Driver behavior braking threshold. Value is in meter per second squared. */ public static final ConfigKey EVENT_BEHAVIOR_BRAKING_THRESHOLD = new ConfigKey<>( "event.behavior.brakingThreshold", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Do not generate alert event if same alert was present in last known location. */ public static final ConfigKey EVENT_IGNORE_DUPLICATE_ALERTS = new ConfigKey<>( "event.ignoreDuplicateAlerts", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * If set to true, invalid positions will be considered for motion logic. */ public static final ConfigKey EVENT_MOTION_PROCESS_INVALID_POSITIONS = new ConfigKey<>( "event.motion.processInvalidPositions", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * If the speed is above specified value, the object is considered to be in motion. Default value is 0.01 knots. */ public static final ConfigKey EVENT_MOTION_SPEED_THRESHOLD = new ConfigKey<>( "event.motion.speedThreshold", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 0.01); /** @@ -282,7 +282,7 @@ public final class Keys { */ public static final ConfigKey GEOFENCE_POLYLINE_DISTANCE = new ConfigKey<>( "geofence.polylineDistance", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 25.0); /** @@ -291,49 +291,49 @@ public final class Keys { */ public static final ConfigKey DATABASE_DRIVER_FILE = new ConfigKey<>( "database.driverFile", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Database driver Java class. For H2 use 'org.h2.Driver'. MySQL driver class name is 'com.mysql.jdbc.Driver'. */ public static final ConfigKey DATABASE_DRIVER = new ConfigKey<>( "database.driver", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Database connection URL. By default Traccar uses H2 database. */ public static final ConfigKey DATABASE_URL = new ConfigKey<>( "database.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Database user name. Default administrator user for H2 database is 'sa'. */ public static final ConfigKey DATABASE_USER = new ConfigKey<>( "database.user", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Database user password. Default password for H2 admin (sa) user is empty. */ public static final ConfigKey DATABASE_PASSWORD = new ConfigKey<>( "database.password", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Path to Liquibase master changelog file. */ public static final ConfigKey DATABASE_CHANGELOG = new ConfigKey<>( "database.changelog", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Database connection pool size. Default value is defined by the HikariCP library. */ public static final ConfigKey DATABASE_MAX_POOL_SIZE = new ConfigKey<>( "database.maxPoolSize", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * SQL query to check connection status. Default value is 'SELECT 1'. For Oracle database you can use @@ -341,7 +341,7 @@ public final class Keys { */ public static final ConfigKey DATABASE_CHECK_CONNECTION = new ConfigKey<>( "database.checkConnection", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "SELECT 1"); /** @@ -349,7 +349,7 @@ public final class Keys { */ public static final ConfigKey DATABASE_SAVE_ORIGINAL = new ConfigKey<>( "database.saveOriginal", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * By default server syncs with the database if it encounters and unknown device. This flag allows to disable that @@ -357,35 +357,35 @@ public final class Keys { */ public static final ConfigKey DATABASE_IGNORE_UNKNOWN = new ConfigKey<>( "database.ignoreUnknown", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Automatically register unknown devices in the database. */ public static final ConfigKey DATABASE_REGISTER_UNKNOWN = new ConfigKey<>( "database.registerUnknown", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Default category for auto-registered devices. */ public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_CATEGORY = new ConfigKey<>( "database.registerUnknown.defaultCategory", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * The group id assigned to auto-registered devices. */ public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_GROUP_ID = new ConfigKey<>( "database.registerUnknown.defaultGroupId", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Minimum device refresh timeout in seconds. Default timeout is 5 minutes. */ public static final ConfigKey DATABASE_REFRESH_DELAY = new ConfigKey<>( "database.refreshDelay", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 300L); /** @@ -393,14 +393,14 @@ public final class Keys { */ public static final ConfigKey DATABASE_SAVE_EMPTY = new ConfigKey<>( "database.saveEmpty", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Device limit for self registered users. Default value is -1, which indicates no limit. */ public static final ConfigKey USERS_DEFAULT_DEVICE_LIMIT = new ConfigKey<>( "users.defaultDeviceLimit", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), -1); /** @@ -408,49 +408,49 @@ public final class Keys { */ public static final ConfigKey USERS_DEFAULT_EXPIRATION_DAYS = new ConfigKey<>( "users.defaultExpirationDays", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP server URL. */ public static final ConfigKey LDAP_URL = new ConfigKey<>( "ldap.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP server login. */ public static final ConfigKey LDAP_USER = new ConfigKey<>( "ldap.user", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP server password. */ public static final ConfigKey LDAP_PASSWORD = new ConfigKey<>( "ldap.password", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Force LDAP authentication. */ public static final ConfigKey LDAP_FORCE = new ConfigKey<>( "ldap.force", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP user search base. */ public static final ConfigKey LDAP_BASE = new ConfigKey<>( "ldap.base", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP attribute used as user id. Default value is 'uid'. */ public static final ConfigKey LDAP_ID_ATTRIBUTE = new ConfigKey<>( "ldap.idAttribute", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "uid"); /** @@ -458,7 +458,7 @@ public final class Keys { */ public static final ConfigKey LDAP_NAME_ATTRIBUTE = new ConfigKey<>( "ldap.nameAttribute", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "cn"); /** @@ -466,7 +466,7 @@ public final class Keys { */ public static final ConfigKey LDAP_MAIN_ATTRIBUTE = new ConfigKey<>( "ldap.mailAttribute", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "mail"); /** @@ -474,21 +474,21 @@ public final class Keys { */ public static final ConfigKey LDAP_SEARCH_FILTER = new ConfigKey<>( "ldap.searchFilter", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP custom admin search filter. */ public static final ConfigKey LDAP_ADMIN_FILTER = new ConfigKey<>( "ldap.adminFilter", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * LDAP admin user group. Used if custom admin filter is not specified. */ public static final ConfigKey LDAP_ADMIN_GROUP = new ConfigKey<>( "ldap.adminGroup", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * If no data is reported by a device for the given amount of time, status changes from online to unknown. Value is @@ -496,7 +496,7 @@ public final class Keys { */ public static final ConfigKey STATUS_TIMEOUT = new ConfigKey<>( "status.timeout", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 600L); /** @@ -504,7 +504,7 @@ public final class Keys { */ public static final ConfigKey STATUS_UPDATE_DEVICE_STATE = new ConfigKey<>( "status.updateDeviceState", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * List of protocol names to ignore offline status. Can be useful to not trigger status change when devices are @@ -512,7 +512,7 @@ public final class Keys { */ public static final ConfigKey STATUS_IGNORE_OFFLINE = new ConfigKey<>( "status.ignoreOffline", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Path to the media folder. Server stores audio, video and photo files in that folder. Sub-folders will be @@ -520,7 +520,7 @@ public final class Keys { */ public static final ConfigKey MEDIA_PATH = new ConfigKey<>( "media.path", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Optional parameter to specify network interface for web interface to bind to. By default server will bind to all @@ -528,7 +528,7 @@ public final class Keys { */ public static final ConfigKey WEB_ADDRESS = new ConfigKey<>( "web.address", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Web interface TCP port number. By default Traccar uses port 8082. To avoid specifying port in the browser you @@ -536,7 +536,7 @@ public final class Keys { */ public static final ConfigKey WEB_PORT = new ConfigKey<>( "web.port", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Sanitize all strings returned via API. This is needed to fix XSS issues in the old web interface. New React-based @@ -544,21 +544,21 @@ public final class Keys { */ public static final ConfigKey WEB_SANITIZE = new ConfigKey<>( "web.sanitize", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Path to the web app folder. */ public static final ConfigKey WEB_PATH = new ConfigKey<>( "web.path", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * WebSocket connection timeout in milliseconds. Default timeout is 10 minutes. */ public static final ConfigKey WEB_TIMEOUT = new ConfigKey<>( "web.timeout", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 60000L); /** @@ -566,14 +566,14 @@ public final class Keys { */ public static final ConfigKey WEB_SESSION_TIMEOUT = new ConfigKey<>( "web.sessionTimeout", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable database access console via '/console' URL. Use only for debugging. Never use in production. */ public static final ConfigKey WEB_CONSOLE = new ConfigKey<>( "web.console", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Server debug version of the web app. Not recommended to use for performance reasons. It is intended to be used @@ -581,21 +581,21 @@ public final class Keys { */ public static final ConfigKey WEB_DEBUG = new ConfigKey<>( "web.debug", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Cross-origin resource sharing origin header value. */ public static final ConfigKey WEB_ORIGIN = new ConfigKey<>( "web.origin", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Cache control header value. By default resources are cached for one hour. */ public static final ConfigKey WEB_CACHE_CONTROL = new ConfigKey<>( "web.cacheControl", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "max-age=3600,public"); /** @@ -604,21 +604,21 @@ public final class Keys { */ public static final ConfigKey FORWARD_URL = new ConfigKey<>( "forward.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Additional HTTP header, can be used for authorization. */ public static final ConfigKey FORWARD_HEADER = new ConfigKey<>( "forward.header", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean value to enable forwarding in JSON format. */ public static final ConfigKey FORWARD_JSON = new ConfigKey<>( "forward.json", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean value to enable URL parameters in json mode. For example, {uniqueId} for device identifier, @@ -626,7 +626,7 @@ public final class Keys { */ public static final ConfigKey FORWARD_URL_VARIABLES = new ConfigKey<>( "forward.urlVariables", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Position forwarding retrying enable. When enabled, additional attempts are made to deliver positions. If initial @@ -637,7 +637,7 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_ENABLE = new ConfigKey<>( "forward.retry.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Position forwarding retry first delay in milliseconds. @@ -645,7 +645,7 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_DELAY = new ConfigKey<>( "forward.retry.delay", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Position forwarding retry maximum retries. @@ -653,7 +653,7 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_COUNT = new ConfigKey<>( "forward.retry.count", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Position forwarding retry pending positions limit. @@ -661,14 +661,14 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_LIMIT = new ConfigKey<>( "forward.retry.limit", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Events forwarding URL. */ public static final ConfigKey EVENT_FORWARD_URL = new ConfigKey<>( "event.forward.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Events forwarding headers. Example value: @@ -677,7 +677,7 @@ public final class Keys { */ public static final ConfigKey EVENT_FORWARD_HEADERS = new ConfigKey<>( "event.forward.header", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable commands queuing when devices are offline. Commands are buffered in memory only, so restarting service @@ -685,14 +685,14 @@ public final class Keys { */ public static final ConfigKey COMMANDS_QUEUEING = new ConfigKey<>( "commands.queueing", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Root folder for all template files. */ public static final ConfigKey TEMPLATES_ROOT = new ConfigKey<>( "templates.root", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "templates"); /** @@ -700,14 +700,14 @@ public final class Keys { */ public static final ConfigKey SMS_HTTP_URL = new ConfigKey<>( "sms.http.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * SMS API authorization header name. Default value is 'Authorization'. */ public static final ConfigKey SMS_HTTP_AUTHORIZATION_HEADER = new ConfigKey<>( "sms.http.authorizationHeader", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "Authorization"); /** @@ -715,21 +715,21 @@ public final class Keys { */ public static final ConfigKey SMS_HTTP_AUTHORIZATION = new ConfigKey<>( "sms.http.authorization", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * SMS API basic authentication user. */ public static final ConfigKey SMS_HTTP_USER = new ConfigKey<>( "sms.http.user", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * SMS API basic authentication password. */ public static final ConfigKey SMS_HTTP_PASSWORD = new ConfigKey<>( "sms.http.password", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * SMS API body template. Placeholders {phone} and {message} can be used in the template. @@ -737,21 +737,21 @@ public final class Keys { */ public static final ConfigKey SMS_HTTP_TEMPLATE = new ConfigKey<>( "sms.http.template", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * AWS Access Key with SNS permission. */ public static final ConfigKey SMS_AWS_ACCESS = new ConfigKey<>( "sms.aws.access", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * AWS Secret Access Key with SNS permission. */ public static final ConfigKey SMS_AWS_SECRET = new ConfigKey<>( "sms.aws.secret", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * AWS Region for SNS service. @@ -759,7 +759,7 @@ public final class Keys { */ public static final ConfigKey SMS_AWS_REGION = new ConfigKey<>( "sms.aws.region", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enabled notification options. Comma-separated string is expected. @@ -767,56 +767,56 @@ public final class Keys { */ public static final ConfigKey NOTIFICATOR_TYPES = new ConfigKey<>( "notificator.types", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Traccar notification API key. */ public static final ConfigKey NOTIFICATOR_TRACCAR_KEY = new ConfigKey<>( "notificator.traccar.key", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Firebase server API key for push notifications. */ public static final ConfigKey NOTIFICATOR_FIREBASE_KEY = new ConfigKey<>( "notificator.firebase.key", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Pushover notification user name. */ public static final ConfigKey NOTIFICATOR_PUSHOVER_USER = new ConfigKey<>( "notificator.pushover.user", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Pushover notification user token. */ public static final ConfigKey NOTIFICATOR_PUSHOVER_TOKEN = new ConfigKey<>( "notificator.pushover.token", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Telegram notification API key. */ public static final ConfigKey NOTIFICATOR_TELEGRAM_KEY = new ConfigKey<>( "notificator.telegram.key", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Telegram notification chat id to post messages to. */ public static final ConfigKey NOTIFICATOR_TELEGRAM_CHAT_ID = new ConfigKey<>( "notificator.telegram.chatId", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Telegram notification send location message. */ public static final ConfigKey NOTIFICATOR_TELEGRAM_SEND_LOCATION = new ConfigKey<>( "notificator.telegram.sendLocation", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Maximum time period for reports in seconds. Can be useful to prevent users to request unreasonably long reports. @@ -824,14 +824,14 @@ public final class Keys { */ public static final ConfigKey REPORT_PERIOD_LIMIT = new ConfigKey<>( "report.periodLimit", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Trips less than minimal duration and minimal distance are ignored. 300 seconds and 500 meters are default. */ public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DISTANCE = new ConfigKey<>( "report.trip.minimalTripDistance", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 500L); /** @@ -839,7 +839,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DURATION = new ConfigKey<>( "report.trip.minimalTripDuration", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 300L); /** @@ -847,7 +847,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_MINIMAL_PARKING_DURATION = new ConfigKey<>( "report.trip.minimalParkingDuration", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 300L); /** @@ -855,7 +855,7 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_MINIMAL_NO_DATA_DURATION = new ConfigKey<>( "report.trip.minimalNoDataDuration", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), 3600L); /** @@ -863,21 +863,21 @@ public final class Keys { */ public static final ConfigKey REPORT_TRIP_USE_IGNITION = new ConfigKey<>( "report.trip.useIgnition", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to enable or disable position filtering. */ public static final ConfigKey FILTER_ENABLE = new ConfigKey<>( "filter.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter invalid (valid field is set to false) positions. */ public static final ConfigKey FILTER_INVALID = new ConfigKey<>( "filter.invalid", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter zero coordinates. Zero latitude and longitude are theoretically valid values, but it practice it usually @@ -885,14 +885,14 @@ public final class Keys { */ public static final ConfigKey FILTER_ZERO = new ConfigKey<>( "filter.zero", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter duplicate records (duplicates are detected by time value). */ public static final ConfigKey FILTER_DUPLICATE = new ConfigKey<>( "filter.duplicate", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter records with fix time in future. The values is specified in seconds. Records that have fix time more than @@ -900,28 +900,28 @@ public final class Keys { */ public static final ConfigKey FILTER_FUTURE = new ConfigKey<>( "filter.future", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter positions with accuracy less than specified value in meters. */ public static final ConfigKey FILTER_ACCURACY = new ConfigKey<>( "filter.accuracy", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter cell and wifi locations that are coming from geolocation provider. */ public static final ConfigKey FILTER_APPROXIMATE = new ConfigKey<>( "filter.approximate", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter positions with exactly zero speed values. */ public static final ConfigKey FILTER_STATIC = new ConfigKey<>( "filter.static", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter records by distance. The values is specified in meters. If the new position is less far than this value @@ -929,7 +929,7 @@ public final class Keys { */ public static final ConfigKey FILTER_DISTANCE = new ConfigKey<>( "filter.distance", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if Position @@ -940,14 +940,14 @@ public final class Keys { */ public static final ConfigKey FILTER_MAX_SPEED = new ConfigKey<>( "filter.maxSpeed", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Filter position if time from previous position is less than specified value in seconds. */ public static final ConfigKey FILTER_MIN_PERIOD = new ConfigKey<>( "filter.minPeriod", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * If false, the server expects all locations to come sequentially (for each device). Filter checks for duplicates, @@ -959,7 +959,7 @@ public final class Keys { */ public static final ConfigKey FILTER_RELATIVE = new ConfigKey<>( "filter.relative", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Time limit for the filtering in seconds. If the time difference between the last position was received by server @@ -967,7 +967,7 @@ public final class Keys { */ public static final ConfigKey FILTER_SKIP_LIMIT = new ConfigKey<>( "filter.skipLimit", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable attributes skipping. Attribute skipping can be enabled in the config or device attributes. @@ -975,14 +975,14 @@ public final class Keys { */ public static final ConfigKey FILTER_SKIP_ATTRIBUTES_ENABLE = new ConfigKey<>( "filter.skipAttributes.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Override device time. Possible values are 'deviceTime' and 'serverTime' */ public static final ConfigKey TIME_OVERRIDE = new ConfigKey<>( "time.override", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * List of protocols for overriding time. If not specified override is applied globally. List consist of protocol @@ -990,7 +990,7 @@ public final class Keys { */ public static final ConfigKey TIME_PROTOCOLS = new ConfigKey<>( "time.protocols", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Replaces coordinates with last known if change is less than a 'coordinates.minError' meters @@ -999,14 +999,14 @@ public final class Keys { */ public static final ConfigKey COORDINATES_FILTER = new ConfigKey<>( "coordinates.filter", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Distance in meters. Distances below this value gets handled like explained in 'coordinates.filter'. */ public static final ConfigKey COORDINATES_MIN_ERROR = new ConfigKey<>( "coordinates.minError", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Distance in meters. Distances above this value gets handled like explained in 'coordinates.filter', but only if @@ -1014,14 +1014,14 @@ public final class Keys { */ public static final ConfigKey COORDINATES_MAX_ERROR = new ConfigKey<>( "coordinates.maxError", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable to save device IP addresses information. Disabled by default. */ public static final ConfigKey PROCESSING_REMOTE_ADDRESS_ENABLE = new ConfigKey<>( "processing.remoteAddress.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable copying of missing attributes from last position to the current one. Might be useful if device doesn't @@ -1029,21 +1029,21 @@ public final class Keys { */ public static final ConfigKey PROCESSING_COPY_ATTRIBUTES_ENABLE = new ConfigKey<>( "processing.copyAttributes.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enable computed attributes processing. */ public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new ConfigKey<>( "processing.computedAttributes.deviceAttributes", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to enable or disable reverse geocoder. */ public static final ConfigKey GEOCODER_ENABLE = new ConfigKey<>( "geocoder.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Reverse geocoder type. Check reverse geocoding documentation for more info. By default (if the value is not @@ -1051,63 +1051,63 @@ public final class Keys { */ public static final ConfigKey GEOCODER_TYPE = new ConfigKey<>( "geocoder.type", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Geocoder server URL. Applicable only to Nominatim and Gisgraphy providers. */ public static final ConfigKey GEOCODER_URL = new ConfigKey<>( "geocoder.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * App id for use with Here provider. */ public static final ConfigKey GEOCODER_ID = new ConfigKey<>( "geocoder.id", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Provider API key. Most providers require API keys. */ public static final ConfigKey GEOCODER_KEY = new ConfigKey<>( "geocoder.key", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Language parameter for providers that support localization (e.g. Google and Nominatim). */ public static final ConfigKey GEOCODER_LANGUAGE = new ConfigKey<>( "geocoder.language", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Address format string. Default value is %h %r, %t, %s, %c. See AddressFormat for more info. */ public static final ConfigKey GEOCODER_FORMAT = new ConfigKey<>( "geocoder.format", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Cache size for geocoding results. */ public static final ConfigKey GEOCODER_CACHE_SIZE = new ConfigKey<>( "geocoder.cacheSize", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Disable automatic reverse geocoding requests for all positions. */ public static final ConfigKey GEOCODER_IGNORE_POSITIONS = new ConfigKey<>( "geocoder.ignorePositions", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to apply reverse geocoding to invalid positions. */ public static final ConfigKey GEOCODER_PROCESS_INVALID_POSITIONS = new ConfigKey<>( "geocoder.processInvalidPositions", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Optional parameter to specify minimum distance for new reverse geocoding request. If distance is less than @@ -1115,14 +1115,14 @@ public final class Keys { */ public static final ConfigKey GEOCODER_REUSE_DISTANCE = new ConfigKey<>( "geocoder.reuseDistance", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Perform geocoding when preparing reports and sending notifications. */ public static final ConfigKey GEOCODER_ON_REQUEST = new ConfigKey<>( "geocoder.onRequest", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to enable LBS location resolution. Some devices send cell towers information and WiFi point when GPS @@ -1131,7 +1131,7 @@ public final class Keys { */ public static final ConfigKey GEOLOCATION_ENABLE = new ConfigKey<>( "geolocation.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Provider to use for LBS location. Available options: google, mozilla and opencellid. By default opencellid is @@ -1140,63 +1140,63 @@ public final class Keys { */ public static final ConfigKey GEOLOCATION_TYPE = new ConfigKey<>( "geolocation.type", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Geolocation provider API URL address. Not required for most providers. */ public static final ConfigKey GEOLOCATION_URL = new ConfigKey<>( "geolocation.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Provider API key. OpenCellID service requires API key. */ public static final ConfigKey GEOLOCATION_KEY = new ConfigKey<>( "geolocation.key", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to apply geolocation to invalid positions. */ public static final ConfigKey GEOLOCATION_PROCESS_INVALID_POSITIONS = new ConfigKey<>( "geolocation.processInvalidPositions", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Default MCC value to use if device doesn't report MCC. */ public static final ConfigKey GEOLOCATION_MCC = new ConfigKey<>( "geolocation.mcc", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Default MNC value to use if device doesn't report MNC. */ public static final ConfigKey GEOLOCATION_MNC = new ConfigKey<>( "geolocation.mnc", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Boolean flag to enable speed limit API to get speed limit values depending on location. Default value is false. */ public static final ConfigKey SPEED_LIMIT_ENABLE = new ConfigKey<>( "speedLimit.enable", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Provider to use for speed limit. Available options: overpass. By default overpass is used. */ public static final ConfigKey SPEED_LIMIT_TYPE = new ConfigKey<>( "speedLimit.type", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Speed limit provider API URL address. */ public static final ConfigKey SPEED_LIMIT_URL = new ConfigKey<>( "speedLimit.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Override latitude sign / hemisphere. Useful in cases where value is incorrect because of device bug. Value can be @@ -1204,7 +1204,7 @@ public final class Keys { */ public static final ConfigKey LOCATION_LATITUDE_HEMISPHERE = new ConfigKey<>( "location.latitudeHemisphere", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Override longitude sign / hemisphere. Useful in cases where value is incorrect because of device bug. Value can @@ -1212,7 +1212,7 @@ public final class Keys { */ public static final ConfigKey LOCATION_LONGITUDE_HEMISPHERE = new ConfigKey<>( "location.longitudeHemisphere", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Jetty Request Log Path. @@ -1222,21 +1222,21 @@ public final class Keys { */ public static final ConfigKey WEB_REQUEST_LOG_PATH = new ConfigKey<>( "web.requestLog.path", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Set the number of days before rotated request log files are deleted. */ public static final ConfigKey WEB_REQUEST_LOG_RETAIN_DAYS = new ConfigKey<>( "web.requestLog.retainDays", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Disable systemd health checks. */ public static final ConfigKey WEB_DISABLE_HEALTH_CHECK = new ConfigKey<>( "web.disableHealthCheck", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Sets SameSite cookie attribute value. @@ -1244,14 +1244,14 @@ public final class Keys { */ public static final ConfigKey WEB_SAME_SITE_COOKIE = new ConfigKey<>( "web.sameSiteCookie", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Enables persisting Jetty session to the database */ public static final ConfigKey WEB_PERSIST_SESSION = new ConfigKey<>( "web.persistSession", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Public URL for the web app. Used for notification and report link. @@ -1260,28 +1260,28 @@ public final class Keys { */ public static final ConfigKey WEB_URL = new ConfigKey<>( "web.url", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Output logging to the standard terminal output instead of a log file. */ public static final ConfigKey LOGGER_CONSOLE = new ConfigKey<>( "logger.console", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Log executed SQL queries. */ public static final ConfigKey LOGGER_QUERIES = new ConfigKey<>( "logger.queries", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Log file name. For rotating logs, a date is added at the end of the file name for non-current logs. */ public static final ConfigKey LOGGER_FILE = new ConfigKey<>( "logger.file", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Logging level. Default value is 'info'. @@ -1289,14 +1289,14 @@ public final class Keys { */ public static final ConfigKey LOGGER_LEVEL = new ConfigKey<>( "logger.level", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Print full exception traces. Useful for debugging. By default shortened traces are logged. */ public static final ConfigKey LOGGER_FULL_STACK_TRACES = new ConfigKey<>( "logger.fullStackTraces", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Create a new log file daily. Helps with log management. For example, downloading and cleaning logs. Enabled by @@ -1304,14 +1304,14 @@ public final class Keys { */ public static final ConfigKey LOGGER_ROTATE = new ConfigKey<>( "logger.rotate", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * A list of position attributes to log. */ public static final ConfigKey LOGGER_ATTRIBUTES = new ConfigKey<>( "logger.attributes", - Collections.singletonList(KeyType.GLOBAL), + Collections.singletonList(KeyType.CONFIG), "time,position,speed,course,accuracy,result"); /** @@ -1319,13 +1319,13 @@ public final class Keys { */ public static final ConfigKey BROADCAST_ADDRESS = new ConfigKey<>( "broadcast.address", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); /** * Multicast port for broadcasting synchronization events. */ public static final ConfigKey BROADCAST_PORT = new ConfigKey<>( "broadcast.port", - Collections.singletonList(KeyType.GLOBAL)); + Collections.singletonList(KeyType.CONFIG)); } -- cgit v1.2.3 From c248ed30047a0525bf792730a0fbd4de0c89ad8e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 10:00:52 -0700 Subject: Refactor attribute lookup --- src/main/java/org/traccar/BaseProtocolDecoder.java | 14 +- src/main/java/org/traccar/config/ConfigKey.java | 73 +- src/main/java/org/traccar/config/ConfigSuffix.java | 81 ++- src/main/java/org/traccar/config/Keys.java | 779 ++++++++++++--------- .../java/org/traccar/database/DeviceManager.java | 57 -- .../java/org/traccar/database/IdentityManager.java | 11 - .../java/org/traccar/handler/FilterHandler.java | 48 +- .../org/traccar/handler/HemisphereHandler.java | 2 +- .../handler/events/FuelDropEventHandler.java | 25 +- .../handler/events/OverspeedEventHandler.java | 13 +- .../org/traccar/helper/model/AttributeUtil.java | 72 ++ src/main/java/org/traccar/model/CellTower.java | 2 +- .../traccar/protocol/StarLinkProtocolDecoder.java | 14 +- .../traccar/protocol/SuntechProtocolDecoder.java | 25 +- .../org/traccar/session/ConnectionManager.java | 5 +- .../org/traccar/session/cache/CacheManager.java | 4 + src/test/java/org/traccar/BaseTest.java | 15 +- .../org/traccar/handler/FilterHandlerTest.java | 21 +- .../handler/events/OverspeedEventHandlerTest.java | 2 +- 19 files changed, 748 insertions(+), 515 deletions(-) create mode 100644 src/main/java/org/traccar/helper/model/AttributeUtil.java diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index cbcb429b3..076b52e96 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -23,11 +23,13 @@ import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import javax.inject.Inject; @@ -46,6 +48,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private final Protocol protocol; private IdentityManager identityManager; + private CacheManager cacheManager; private ConnectionManager connectionManager; private StatisticsManager statisticsManager; private MediaManager mediaManager; @@ -64,6 +67,15 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { this.identityManager = identityManager; } + public CacheManager getCacheManager() { + return cacheManager; + } + + @Inject + public void setCacheManager(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + @Inject public void setConnectionManager(ConnectionManager connectionManager) { this.connectionManager = connectionManager; @@ -125,7 +137,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, false, true); + String timeZoneName = AttributeUtil.lookup(cacheManager, Keys.DECODER_TIMEZONE, deviceId); if (timeZoneName != null) { result = TimeZone.getTimeZone(timeZoneName); } diff --git a/src/main/java/org/traccar/config/ConfigKey.java b/src/main/java/org/traccar/config/ConfigKey.java index c046a46a5..b8151392c 100644 --- a/src/main/java/org/traccar/config/ConfigKey.java +++ b/src/main/java/org/traccar/config/ConfigKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,30 +15,34 @@ */ package org.traccar.config; +import java.util.HashSet; import java.util.List; +import java.util.Set; -public class ConfigKey { +public abstract class ConfigKey { private final String key; - private final List types; + private final Set types = new HashSet<>(); + private final Class valueClass; private final T defaultValue; - ConfigKey(String key, List types) { - this(key, types, null); - } - - ConfigKey(String key, List types, T defaultValue) { + ConfigKey(String key, List types, Class valueClass, T defaultValue) { this.key = key; - this.types = types; + this.types.addAll(types); + this.valueClass = valueClass; this.defaultValue = defaultValue; } - String getKey() { + public String getKey() { return key; } - public List getTypes() { - return types; + public boolean hasType(KeyType type) { + return types.contains(type); + } + + public Class getValueClass() { + return valueClass; } public T getDefaultValue() { @@ -46,3 +50,48 @@ public class ConfigKey { } } + +class StringConfigKey extends ConfigKey { + StringConfigKey(String key, List types) { + super(key, types, String.class, null); + } + StringConfigKey(String key, List types, String defaultValue) { + super(key, types, String.class, defaultValue); + } +} + +class BooleanConfigKey extends ConfigKey { + BooleanConfigKey(String key, List types) { + super(key, types, Boolean.class, null); + } + BooleanConfigKey(String key, List types, Boolean defaultValue) { + super(key, types, Boolean.class, defaultValue); + } +} + +class IntegerConfigKey extends ConfigKey { + IntegerConfigKey(String key, List types) { + super(key, types, Integer.class, null); + } + IntegerConfigKey(String key, List types, Integer defaultValue) { + super(key, types, Integer.class, defaultValue); + } +} + +class LongConfigKey extends ConfigKey { + LongConfigKey(String key, List types) { + super(key, types, Long.class, null); + } + LongConfigKey(String key, List types, Long defaultValue) { + super(key, types, Long.class, defaultValue); + } +} + +class DoubleConfigKey extends ConfigKey { + DoubleConfigKey(String key, List types) { + super(key, types, Double.class, null); + } + DoubleConfigKey(String key, List types, Double defaultValue) { + super(key, types, Double.class, defaultValue); + } +} diff --git a/src/main/java/org/traccar/config/ConfigSuffix.java b/src/main/java/org/traccar/config/ConfigSuffix.java index ede4c107d..aac3219c6 100644 --- a/src/main/java/org/traccar/config/ConfigSuffix.java +++ b/src/main/java/org/traccar/config/ConfigSuffix.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2019 - 2022 Anton Tananaev (anton@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.config; import java.util.List; -public class ConfigSuffix { +public abstract class ConfigSuffix { - private final String keySuffix; - private final List types; - private final T defaultValue; - - ConfigSuffix(String keySuffix, List types) { - this(keySuffix, types, null); - } + protected final String keySuffix; + protected final List types; + protected final T defaultValue; ConfigSuffix(String keySuffix, List types, T defaultValue) { this.keySuffix = keySuffix; @@ -33,8 +29,71 @@ public class ConfigSuffix { this.defaultValue = defaultValue; } - public ConfigKey withPrefix(String prefix) { - return new ConfigKey<>(prefix + keySuffix, types, defaultValue); + public abstract ConfigKey withPrefix(String prefix); + +} + +class StringConfigSuffix extends ConfigSuffix { + StringConfigSuffix(String key, List types) { + super(key, types, null); + } + StringConfigSuffix(String key, List types, String defaultValue) { + super(key, types, defaultValue); + } + @Override + public ConfigKey withPrefix(String prefix) { + return new StringConfigKey(prefix + keySuffix, types, defaultValue); + } +} + +class BooleanConfigSuffix extends ConfigSuffix { + BooleanConfigSuffix(String key, List types) { + super(key, types, null); + } + BooleanConfigSuffix(String key, List types, Boolean defaultValue) { + super(key, types, defaultValue); + } + @Override + public ConfigKey withPrefix(String prefix) { + return new BooleanConfigKey(prefix + keySuffix, types, defaultValue); + } +} + +class IntegerConfigSuffix extends ConfigSuffix { + IntegerConfigSuffix(String key, List types) { + super(key, types, null); + } + IntegerConfigSuffix(String key, List types, Integer defaultValue) { + super(key, types, defaultValue); + } + @Override + public ConfigKey withPrefix(String prefix) { + return new IntegerConfigKey(prefix + keySuffix, types, defaultValue); } +} +class LongConfigSuffix extends ConfigSuffix { + LongConfigSuffix(String key, List types) { + super(key, types, null); + } + LongConfigSuffix(String key, List types, Long defaultValue) { + super(key, types, defaultValue); + } + @Override + public ConfigKey withPrefix(String prefix) { + return new LongConfigKey(prefix + keySuffix, types, defaultValue); + } +} + +class DoubleConfigSuffix extends ConfigSuffix { + DoubleConfigSuffix(String key, List types) { + super(key, types, null); + } + DoubleConfigSuffix(String key, List types, Double defaultValue) { + super(key, types, defaultValue); + } + @Override + public ConfigKey withPrefix(String prefix) { + return new DoubleConfigKey(prefix + keySuffix, types, defaultValue); + } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 292202de0..465751d38 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -15,7 +15,7 @@ */ package org.traccar.config; -import java.util.Collections; +import java.util.List; public final class Keys { @@ -25,39 +25,39 @@ public final class Keys { /** * Network interface for a the protocol. If not specified, server will bind all interfaces. */ - public static final ConfigSuffix PROTOCOL_ADDRESS = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_ADDRESS = new StringConfigSuffix( ".address", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Port number for the protocol. Most protocols use TCP on the transport layer. Some protocols use UDP. Some * support both TCP and UDP. */ - public static final ConfigSuffix PROTOCOL_PORT = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_PORT = new IntegerConfigSuffix( ".port", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * List of devices for polling protocols. List should contain unique ids separated by commas. Used only for polling * protocols. */ - public static final ConfigSuffix PROTOCOL_DEVICES = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_DEVICES = new StringConfigSuffix( ".devices", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Polling interval in seconds. Used only for polling protocols. */ - public static final ConfigSuffix PROTOCOL_INTERVAL = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_INTERVAL = new LongConfigSuffix( ".interval", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable SSL support for the protocol. Not all protocols support this. */ - public static final ConfigSuffix PROTOCOL_SSL = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_SSL = new BooleanConfigSuffix( ".ssl", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Connection timeout value in seconds. Because sometimes there is no way to detect lost TCP connection old @@ -65,568 +65,640 @@ public final class Keys { * problems with establishing new connections when number of devices is high or devices data connections are * unstable. */ - public static final ConfigSuffix PROTOCOL_TIMEOUT = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_TIMEOUT = new IntegerConfigSuffix( ".timeout", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Device password. Commonly used in some protocol for sending commands. */ - public static final ConfigSuffix PROTOCOL_DEVICE_PASSWORD = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_DEVICE_PASSWORD = new StringConfigSuffix( ".devicePassword", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Default protocol mask to use. Currently used only by Skypatrol protocol. */ - public static final ConfigSuffix PROTOCOL_MASK = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_MASK = new IntegerConfigSuffix( ".mask", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Custom message length. Currently used only by H2 protocol for specifying binary message length. */ - public static final ConfigSuffix PROTOCOL_MESSAGE_LENGTH = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_MESSAGE_LENGTH = new IntegerConfigSuffix( ".messageLength", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable extended functionality for the protocol. The reason it's disabled by default is that not all devices * support it. */ - public static final ConfigSuffix PROTOCOL_EXTENDED = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_EXTENDED = new BooleanConfigSuffix( ".extended", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Decode string as UTF8 instead of ASCII. Only applicable for some protocols. */ - public static final ConfigSuffix PROTOCOL_UTF8 = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_UTF8 = new BooleanConfigSuffix( ".utf8", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable CAN decoding for the protocol. Similar to 'extended' configuration, it's not supported for some devices. */ - public static final ConfigSuffix PROTOCOL_CAN = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_CAN = new BooleanConfigSuffix( ".can", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Indicates whether server acknowledgement is required. Only applicable for some protocols. */ - public static final ConfigSuffix PROTOCOL_ACK = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_ACK = new BooleanConfigSuffix( ".ack", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Ignore device reported fix time. Useful in case some devices report invalid time. Currently only available for * GL200 protocol. */ - public static final ConfigSuffix PROTOCOL_IGNORE_FIX_TIME = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_IGNORE_FIX_TIME = new BooleanConfigSuffix( ".ignoreFixTime", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Decode additional TK103 attributes. Not supported for some devices. */ - public static final ConfigSuffix PROTOCOL_DECODE_LOW = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_DECODE_LOW = new BooleanConfigSuffix( ".decodeLow", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Use long date format for Atrack protocol. */ - public static final ConfigSuffix PROTOCOL_LONG_DATE = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_LONG_DATE = new BooleanConfigSuffix( ".longDate", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Use decimal fuel value format for Atrack protocol. */ - public static final ConfigSuffix PROTOCOL_DECIMAL_FUEL = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_DECIMAL_FUEL = new BooleanConfigSuffix( ".decimalFuel", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Indicates additional custom attributes for Atrack protocol. */ - public static final ConfigSuffix PROTOCOL_CUSTOM = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_CUSTOM = new BooleanConfigSuffix( ".custom", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Custom format string for Atrack protocol. */ - public static final ConfigSuffix PROTOCOL_FORM = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_FORM = new StringConfigSuffix( ".form", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Protocol configuration. Required for some devices for decoding incoming data. */ - public static final ConfigSuffix PROTOCOL_CONFIG = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_CONFIG = new StringConfigSuffix( ".config", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Alarm mapping for Atrack protocol. */ - public static final ConfigSuffix PROTOCOL_ALARM_MAP = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_ALARM_MAP = new StringConfigSuffix( ".alarmMap", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Indicates whether TAIP protocol should have prefixes for messages. */ - public static final ConfigSuffix PROTOCOL_PREFIX = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_PREFIX = new BooleanConfigSuffix( ".prefix", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Some devices require server address confirmation. Use this parameter to configure correct public address. */ - public static final ConfigSuffix PROTOCOL_SERVER = new ConfigSuffix<>( + public static final ConfigSuffix PROTOCOL_SERVER = new StringConfigSuffix( ".server", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); + + /** + * Protocol type for Suntech. + */ + public static final ConfigKey PROTOCOL_TYPE = new IntegerConfigKey( + "suntech.protocolType", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + + /** + * Suntech HBM configuration value. + */ + public static final ConfigKey PROTOCOL_HBM = new BooleanConfigKey( + "suntech.hbm", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + + /** + * Format includes ADC value. + */ + public static final ConfigSuffix PROTOCOL_INCLUDE_ADC = new BooleanConfigSuffix( + ".includeAdc", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + + /** + * Format includes RPM value. + */ + public static final ConfigSuffix PROTOCOL_INCLUDE_RPM = new BooleanConfigSuffix( + ".includeRpm", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + + /** + * Format includes temperature values. + */ + public static final ConfigSuffix PROTOCOL_INCLUDE_TEMPERATURE = new BooleanConfigSuffix( + ".includeTemp", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + + /** + * Protocol format. Used by protocols that have configurable message format. + */ + public static final ConfigSuffix PROTOCOL_FORMAT = new StringConfigSuffix( + ".format", + List.of(KeyType.DEVICE)); + + /** + * Protocol date format. Used by protocols that have configurable date format. + */ + public static final ConfigSuffix PROTOCOL_DATE_FORMAT = new StringConfigSuffix( + ".dateFormat", + List.of(KeyType.DEVICE)); + + /** + * Device time zone. Most devices report UTC time, but in some cases devices report local time, so this parameter + * needs to be configured for the server to be able to decode the time correctly. + */ + public static final ConfigKey DECODER_TIMEZONE = new StringConfigKey( + "decoder.timezone", + List.of(KeyType.CONFIG, KeyType.DEVICE)); /** * ORBCOMM API access id. */ - public static final ConfigKey ORBCOMM_ACCESS_ID = new ConfigKey<>( + public static final ConfigKey ORBCOMM_ACCESS_ID = new StringConfigKey( "orbcomm.accessId", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * ORBCOMM API password. */ - public static final ConfigKey ORBCOMM_PASSWORD = new ConfigKey<>( + public static final ConfigKey ORBCOMM_PASSWORD = new StringConfigKey( "orbcomm.password", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Server wide connection timeout value in seconds. See protocol timeout for more information. */ - public static final ConfigKey SERVER_TIMEOUT = new ConfigKey<>( + public static final ConfigKey SERVER_TIMEOUT = new IntegerConfigKey( "server.timeout", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Address for uploading aggregated anonymous usage statistics. Uploaded information is the same you can see on the * statistics screen in the web app. It does not include any sensitive (e.g. locations). */ - public static final ConfigKey SERVER_STATISTICS = new ConfigKey<>( + public static final ConfigKey SERVER_STATISTICS = new StringConfigKey( "server.statistics", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); + + /** + * Fuel drop threshold value. When fuel level drops from one position to another for more the value, an event is + * generated. + */ + public static final ConfigKey EVENT_FUEL_DROP_THRESHOLD = new DoubleConfigKey( + "fuelDropThreshold", + List.of(KeyType.SERVER, KeyType.DEVICE)); + + /** + * Speed limit value in knots. + */ + public static final ConfigKey EVENT_OVERSPEED_LIMIT = new DoubleConfigKey( + "speedLimit", + List.of(KeyType.SERVER, KeyType.DEVICE)); /** * If true, the event is generated once at the beginning of overspeeding period. */ - public static final ConfigKey EVENT_OVERSPEED_NOT_REPEAT = new ConfigKey<>( + public static final ConfigKey EVENT_OVERSPEED_NOT_REPEAT = new BooleanConfigKey( "event.overspeed.notRepeat", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Minimal over speed duration to trigger the event. Value in seconds. */ - public static final ConfigKey EVENT_OVERSPEED_MINIMAL_DURATION = new ConfigKey<>( + public static final ConfigKey EVENT_OVERSPEED_MINIMAL_DURATION = new LongConfigKey( "event.overspeed.minimalDuration", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Relevant only for geofence speed limits. Use the lowest speed limit from all geofences. */ - public static final ConfigKey EVENT_OVERSPEED_PREFER_LOWEST = new ConfigKey<>( + public static final ConfigKey EVENT_OVERSPEED_PREFER_LOWEST = new BooleanConfigKey( "event.overspeed.preferLowest", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Driver behavior acceleration threshold. Value is in meter per second squared. */ - public static final ConfigKey EVENT_BEHAVIOR_ACCELERATION_THRESHOLD = new ConfigKey<>( + public static final ConfigKey EVENT_BEHAVIOR_ACCELERATION_THRESHOLD = new DoubleConfigKey( "event.behavior.accelerationThreshold", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Driver behavior braking threshold. Value is in meter per second squared. */ - public static final ConfigKey EVENT_BEHAVIOR_BRAKING_THRESHOLD = new ConfigKey<>( + public static final ConfigKey EVENT_BEHAVIOR_BRAKING_THRESHOLD = new DoubleConfigKey( "event.behavior.brakingThreshold", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Do not generate alert event if same alert was present in last known location. */ - public static final ConfigKey EVENT_IGNORE_DUPLICATE_ALERTS = new ConfigKey<>( + public static final ConfigKey EVENT_IGNORE_DUPLICATE_ALERTS = new BooleanConfigKey( "event.ignoreDuplicateAlerts", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * If set to true, invalid positions will be considered for motion logic. */ - public static final ConfigKey EVENT_MOTION_PROCESS_INVALID_POSITIONS = new ConfigKey<>( + public static final ConfigKey EVENT_MOTION_PROCESS_INVALID_POSITIONS = new BooleanConfigKey( "event.motion.processInvalidPositions", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * If the speed is above specified value, the object is considered to be in motion. Default value is 0.01 knots. */ - public static final ConfigKey EVENT_MOTION_SPEED_THRESHOLD = new ConfigKey<>( + public static final ConfigKey EVENT_MOTION_SPEED_THRESHOLD = new DoubleConfigKey( "event.motion.speedThreshold", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 0.01); /** * Global polyline geofence distance. Within that distance from the polyline, point is considered within the * geofence. Each individual geofence can also has 'polylineDistance' attribute which will take precedence. */ - public static final ConfigKey GEOFENCE_POLYLINE_DISTANCE = new ConfigKey<>( + public static final ConfigKey GEOFENCE_POLYLINE_DISTANCE = new DoubleConfigKey( "geofence.polylineDistance", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 25.0); /** * Path to the database driver JAR file. Traccar includes drivers for MySQL, PostgreSQL and H2 databases. If you use * one of those, you don't need to specify this parameter. */ - public static final ConfigKey DATABASE_DRIVER_FILE = new ConfigKey<>( + public static final ConfigKey DATABASE_DRIVER_FILE = new StringConfigKey( "database.driverFile", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Database driver Java class. For H2 use 'org.h2.Driver'. MySQL driver class name is 'com.mysql.jdbc.Driver'. */ - public static final ConfigKey DATABASE_DRIVER = new ConfigKey<>( + public static final ConfigKey DATABASE_DRIVER = new StringConfigKey( "database.driver", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Database connection URL. By default Traccar uses H2 database. */ - public static final ConfigKey DATABASE_URL = new ConfigKey<>( + public static final ConfigKey DATABASE_URL = new StringConfigKey( "database.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Database user name. Default administrator user for H2 database is 'sa'. */ - public static final ConfigKey DATABASE_USER = new ConfigKey<>( + public static final ConfigKey DATABASE_USER = new StringConfigKey( "database.user", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Database user password. Default password for H2 admin (sa) user is empty. */ - public static final ConfigKey DATABASE_PASSWORD = new ConfigKey<>( + public static final ConfigKey DATABASE_PASSWORD = new StringConfigKey( "database.password", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Path to Liquibase master changelog file. */ - public static final ConfigKey DATABASE_CHANGELOG = new ConfigKey<>( + public static final ConfigKey DATABASE_CHANGELOG = new StringConfigKey( "database.changelog", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Database connection pool size. Default value is defined by the HikariCP library. */ - public static final ConfigKey DATABASE_MAX_POOL_SIZE = new ConfigKey<>( + public static final ConfigKey DATABASE_MAX_POOL_SIZE = new IntegerConfigKey( "database.maxPoolSize", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * SQL query to check connection status. Default value is 'SELECT 1'. For Oracle database you can use * 'SELECT 1 FROM DUAL'. */ - public static final ConfigKey DATABASE_CHECK_CONNECTION = new ConfigKey<>( + public static final ConfigKey DATABASE_CHECK_CONNECTION = new StringConfigKey( "database.checkConnection", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "SELECT 1"); /** * Store original HEX or string data as "raw" attribute in the corresponding position. */ - public static final ConfigKey DATABASE_SAVE_ORIGINAL = new ConfigKey<>( + public static final ConfigKey DATABASE_SAVE_ORIGINAL = new BooleanConfigKey( "database.saveOriginal", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * By default server syncs with the database if it encounters and unknown device. This flag allows to disable that * behavior to improve performance in some cases. */ - public static final ConfigKey DATABASE_IGNORE_UNKNOWN = new ConfigKey<>( + public static final ConfigKey DATABASE_IGNORE_UNKNOWN = new BooleanConfigKey( "database.ignoreUnknown", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Automatically register unknown devices in the database. */ - public static final ConfigKey DATABASE_REGISTER_UNKNOWN = new ConfigKey<>( + public static final ConfigKey DATABASE_REGISTER_UNKNOWN = new BooleanConfigKey( "database.registerUnknown", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Default category for auto-registered devices. */ - public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_CATEGORY = new ConfigKey<>( + public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_CATEGORY = new StringConfigKey( "database.registerUnknown.defaultCategory", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * The group id assigned to auto-registered devices. */ - public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_GROUP_ID = new ConfigKey<>( + public static final ConfigKey DATABASE_REGISTER_UNKNOWN_DEFAULT_GROUP_ID = new LongConfigKey( "database.registerUnknown.defaultGroupId", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Minimum device refresh timeout in seconds. Default timeout is 5 minutes. */ - public static final ConfigKey DATABASE_REFRESH_DELAY = new ConfigKey<>( + public static final ConfigKey DATABASE_REFRESH_DELAY = new LongConfigKey( "database.refreshDelay", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 300L); /** * Store empty messages as positions. For example, heartbeats. */ - public static final ConfigKey DATABASE_SAVE_EMPTY = new ConfigKey<>( + public static final ConfigKey DATABASE_SAVE_EMPTY = new BooleanConfigKey( "database.saveEmpty", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Device limit for self registered users. Default value is -1, which indicates no limit. */ - public static final ConfigKey USERS_DEFAULT_DEVICE_LIMIT = new ConfigKey<>( + public static final ConfigKey USERS_DEFAULT_DEVICE_LIMIT = new IntegerConfigKey( "users.defaultDeviceLimit", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), -1); /** * Default user expiration for self registered users. Value is in days. By default no expiration is set. */ - public static final ConfigKey USERS_DEFAULT_EXPIRATION_DAYS = new ConfigKey<>( + public static final ConfigKey USERS_DEFAULT_EXPIRATION_DAYS = new IntegerConfigKey( "users.defaultExpirationDays", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP server URL. */ - public static final ConfigKey LDAP_URL = new ConfigKey<>( + public static final ConfigKey LDAP_URL = new StringConfigKey( "ldap.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP server login. */ - public static final ConfigKey LDAP_USER = new ConfigKey<>( + public static final ConfigKey LDAP_USER = new StringConfigKey( "ldap.user", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP server password. */ - public static final ConfigKey LDAP_PASSWORD = new ConfigKey<>( + public static final ConfigKey LDAP_PASSWORD = new StringConfigKey( "ldap.password", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Force LDAP authentication. */ - public static final ConfigKey LDAP_FORCE = new ConfigKey<>( + public static final ConfigKey LDAP_FORCE = new BooleanConfigKey( "ldap.force", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP user search base. */ - public static final ConfigKey LDAP_BASE = new ConfigKey<>( + public static final ConfigKey LDAP_BASE = new StringConfigKey( "ldap.base", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP attribute used as user id. Default value is 'uid'. */ - public static final ConfigKey LDAP_ID_ATTRIBUTE = new ConfigKey<>( + public static final ConfigKey LDAP_ID_ATTRIBUTE = new StringConfigKey( "ldap.idAttribute", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "uid"); /** * LDAP attribute used as user name. Default value is 'cn'. */ - public static final ConfigKey LDAP_NAME_ATTRIBUTE = new ConfigKey<>( + public static final ConfigKey LDAP_NAME_ATTRIBUTE = new StringConfigKey( "ldap.nameAttribute", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "cn"); /** * LDAP attribute used as user email. Default value is 'mail'. */ - public static final ConfigKey LDAP_MAIN_ATTRIBUTE = new ConfigKey<>( + public static final ConfigKey LDAP_MAIN_ATTRIBUTE = new StringConfigKey( "ldap.mailAttribute", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "mail"); /** * LDAP custom search filter. If not specified, '({idAttribute}=:login)' will be used as a filter. */ - public static final ConfigKey LDAP_SEARCH_FILTER = new ConfigKey<>( + public static final ConfigKey LDAP_SEARCH_FILTER = new StringConfigKey( "ldap.searchFilter", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP custom admin search filter. */ - public static final ConfigKey LDAP_ADMIN_FILTER = new ConfigKey<>( + public static final ConfigKey LDAP_ADMIN_FILTER = new StringConfigKey( "ldap.adminFilter", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * LDAP admin user group. Used if custom admin filter is not specified. */ - public static final ConfigKey LDAP_ADMIN_GROUP = new ConfigKey<>( + public static final ConfigKey LDAP_ADMIN_GROUP = new StringConfigKey( "ldap.adminGroup", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * If no data is reported by a device for the given amount of time, status changes from online to unknown. Value is * in seconds. Default timeout is 10 minutes. */ - public static final ConfigKey STATUS_TIMEOUT = new ConfigKey<>( + public static final ConfigKey STATUS_TIMEOUT = new LongConfigKey( "status.timeout", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 600L); /** * Force additional state check when device status changes to 'offline' or 'unknown'. Default false. */ - public static final ConfigKey STATUS_UPDATE_DEVICE_STATE = new ConfigKey<>( + public static final ConfigKey STATUS_UPDATE_DEVICE_STATE = new BooleanConfigKey( "status.updateDeviceState", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * List of protocol names to ignore offline status. Can be useful to not trigger status change when devices are * configured to disconnect after reporting a batch of data. */ - public static final ConfigKey STATUS_IGNORE_OFFLINE = new ConfigKey<>( + public static final ConfigKey STATUS_IGNORE_OFFLINE = new StringConfigKey( "status.ignoreOffline", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Path to the media folder. Server stores audio, video and photo files in that folder. Sub-folders will be * automatically created for each device by unique id. */ - public static final ConfigKey MEDIA_PATH = new ConfigKey<>( + public static final ConfigKey MEDIA_PATH = new StringConfigKey( "media.path", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Optional parameter to specify network interface for web interface to bind to. By default server will bind to all * available interfaces. */ - public static final ConfigKey WEB_ADDRESS = new ConfigKey<>( + public static final ConfigKey WEB_ADDRESS = new StringConfigKey( "web.address", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Web interface TCP port number. By default Traccar uses port 8082. To avoid specifying port in the browser you * can set it to 80 (default HTTP port). */ - public static final ConfigKey WEB_PORT = new ConfigKey<>( + public static final ConfigKey WEB_PORT = new IntegerConfigKey( "web.port", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Sanitize all strings returned via API. This is needed to fix XSS issues in the old web interface. New React-based * interface doesn't require this. */ - public static final ConfigKey WEB_SANITIZE = new ConfigKey<>( + public static final ConfigKey WEB_SANITIZE = new BooleanConfigKey( "web.sanitize", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Path to the web app folder. */ - public static final ConfigKey WEB_PATH = new ConfigKey<>( + public static final ConfigKey WEB_PATH = new StringConfigKey( "web.path", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * WebSocket connection timeout in milliseconds. Default timeout is 10 minutes. */ - public static final ConfigKey WEB_TIMEOUT = new ConfigKey<>( + public static final ConfigKey WEB_TIMEOUT = new LongConfigKey( "web.timeout", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 60000L); /** * Authentication sessions timeout in seconds. By default no timeout. */ - public static final ConfigKey WEB_SESSION_TIMEOUT = new ConfigKey<>( + public static final ConfigKey WEB_SESSION_TIMEOUT = new IntegerConfigKey( "web.sessionTimeout", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable database access console via '/console' URL. Use only for debugging. Never use in production. */ - public static final ConfigKey WEB_CONSOLE = new ConfigKey<>( + public static final ConfigKey WEB_CONSOLE = new BooleanConfigKey( "web.console", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Server debug version of the web app. Not recommended to use for performance reasons. It is intended to be used * for development and debugging purposes. */ - public static final ConfigKey WEB_DEBUG = new ConfigKey<>( + public static final ConfigKey WEB_DEBUG = new BooleanConfigKey( "web.debug", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Cross-origin resource sharing origin header value. */ - public static final ConfigKey WEB_ORIGIN = new ConfigKey<>( + public static final ConfigKey WEB_ORIGIN = new StringConfigKey( "web.origin", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Cache control header value. By default resources are cached for one hour. */ - public static final ConfigKey WEB_CACHE_CONTROL = new ConfigKey<>( + public static final ConfigKey WEB_CACHE_CONTROL = new StringConfigKey( "web.cacheControl", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "max-age=3600,public"); /** * URL to forward positions. Data is passed through URL parameters. For example, {uniqueId} for device identifier, * {latitude} and {longitude} for coordinates. */ - public static final ConfigKey FORWARD_URL = new ConfigKey<>( + public static final ConfigKey FORWARD_URL = new StringConfigKey( "forward.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Additional HTTP header, can be used for authorization. */ - public static final ConfigKey FORWARD_HEADER = new ConfigKey<>( + public static final ConfigKey FORWARD_HEADER = new StringConfigKey( "forward.header", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean value to enable forwarding in JSON format. */ - public static final ConfigKey FORWARD_JSON = new ConfigKey<>( + public static final ConfigKey FORWARD_JSON = new BooleanConfigKey( "forward.json", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean value to enable URL parameters in json mode. For example, {uniqueId} for device identifier, * {latitude} and {longitude} for coordinates. */ - public static final ConfigKey FORWARD_URL_VARIABLES = new ConfigKey<>( + public static final ConfigKey FORWARD_URL_VARIABLES = new BooleanConfigKey( "forward.urlVariables", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Position forwarding retrying enable. When enabled, additional attempts are made to deliver positions. If initial @@ -635,301 +707,301 @@ public final class Keys { * If forwarding is retried for 'forward.retry.count', retrying is canceled and the position is dropped. Positions * pending to be delivered are limited to 'forward.retry.limit'. If this limit is reached, positions get discarded. */ - public static final ConfigKey FORWARD_RETRY_ENABLE = new ConfigKey<>( + public static final ConfigKey FORWARD_RETRY_ENABLE = new BooleanConfigKey( "forward.retry.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Position forwarding retry first delay in milliseconds. * Can be set to anything greater than 0. Defaults to 100 milliseconds. */ - public static final ConfigKey FORWARD_RETRY_DELAY = new ConfigKey<>( + public static final ConfigKey FORWARD_RETRY_DELAY = new IntegerConfigKey( "forward.retry.delay", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Position forwarding retry maximum retries. * Can be set to anything greater than 0. Defaults to 10 retries. */ - public static final ConfigKey FORWARD_RETRY_COUNT = new ConfigKey<>( + public static final ConfigKey FORWARD_RETRY_COUNT = new IntegerConfigKey( "forward.retry.count", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Position forwarding retry pending positions limit. * Can be set to anything greater than 0. Defaults to 100 positions. */ - public static final ConfigKey FORWARD_RETRY_LIMIT = new ConfigKey<>( + public static final ConfigKey FORWARD_RETRY_LIMIT = new IntegerConfigKey( "forward.retry.limit", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Events forwarding URL. */ - public static final ConfigKey EVENT_FORWARD_URL = new ConfigKey<>( + public static final ConfigKey EVENT_FORWARD_URL = new StringConfigKey( "event.forward.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Events forwarding headers. Example value: * FirstHeader: hello * SecondHeader: world */ - public static final ConfigKey EVENT_FORWARD_HEADERS = new ConfigKey<>( + public static final ConfigKey EVENT_FORWARD_HEADERS = new StringConfigKey( "event.forward.header", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable commands queuing when devices are offline. Commands are buffered in memory only, so restarting service * will clear the buffer. */ - public static final ConfigKey COMMANDS_QUEUEING = new ConfigKey<>( + public static final ConfigKey COMMANDS_QUEUEING = new BooleanConfigKey( "commands.queueing", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Root folder for all template files. */ - public static final ConfigKey TEMPLATES_ROOT = new ConfigKey<>( + public static final ConfigKey TEMPLATES_ROOT = new StringConfigKey( "templates.root", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "templates"); /** * SMS API service full URL. Enables SMS commands and notifications. */ - public static final ConfigKey SMS_HTTP_URL = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_URL = new StringConfigKey( "sms.http.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * SMS API authorization header name. Default value is 'Authorization'. */ - public static final ConfigKey SMS_HTTP_AUTHORIZATION_HEADER = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_AUTHORIZATION_HEADER = new StringConfigKey( "sms.http.authorizationHeader", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "Authorization"); /** * SMS API authorization header value. This value takes precedence over user and password. */ - public static final ConfigKey SMS_HTTP_AUTHORIZATION = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_AUTHORIZATION = new StringConfigKey( "sms.http.authorization", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * SMS API basic authentication user. */ - public static final ConfigKey SMS_HTTP_USER = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_USER = new StringConfigKey( "sms.http.user", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * SMS API basic authentication password. */ - public static final ConfigKey SMS_HTTP_PASSWORD = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_PASSWORD = new StringConfigKey( "sms.http.password", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * SMS API body template. Placeholders {phone} and {message} can be used in the template. * If value starts with '{' or '[', server automatically assumes JSON format. */ - public static final ConfigKey SMS_HTTP_TEMPLATE = new ConfigKey<>( + public static final ConfigKey SMS_HTTP_TEMPLATE = new StringConfigKey( "sms.http.template", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * AWS Access Key with SNS permission. */ - public static final ConfigKey SMS_AWS_ACCESS = new ConfigKey<>( + public static final ConfigKey SMS_AWS_ACCESS = new StringConfigKey( "sms.aws.access", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * AWS Secret Access Key with SNS permission. */ - public static final ConfigKey SMS_AWS_SECRET = new ConfigKey<>( + public static final ConfigKey SMS_AWS_SECRET = new StringConfigKey( "sms.aws.secret", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * AWS Region for SNS service. * Make sure to use regions that are supported for messaging. */ - public static final ConfigKey SMS_AWS_REGION = new ConfigKey<>( + public static final ConfigKey SMS_AWS_REGION = new StringConfigKey( "sms.aws.region", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enabled notification options. Comma-separated string is expected. * Example: web,mail,sms */ - public static final ConfigKey NOTIFICATOR_TYPES = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_TYPES = new StringConfigKey( "notificator.types", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Traccar notification API key. */ - public static final ConfigKey NOTIFICATOR_TRACCAR_KEY = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_TRACCAR_KEY = new StringConfigKey( "notificator.traccar.key", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Firebase server API key for push notifications. */ - public static final ConfigKey NOTIFICATOR_FIREBASE_KEY = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_FIREBASE_KEY = new StringConfigKey( "notificator.firebase.key", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Pushover notification user name. */ - public static final ConfigKey NOTIFICATOR_PUSHOVER_USER = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_PUSHOVER_USER = new StringConfigKey( "notificator.pushover.user", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Pushover notification user token. */ - public static final ConfigKey NOTIFICATOR_PUSHOVER_TOKEN = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_PUSHOVER_TOKEN = new StringConfigKey( "notificator.pushover.token", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Telegram notification API key. */ - public static final ConfigKey NOTIFICATOR_TELEGRAM_KEY = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_TELEGRAM_KEY = new StringConfigKey( "notificator.telegram.key", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Telegram notification chat id to post messages to. */ - public static final ConfigKey NOTIFICATOR_TELEGRAM_CHAT_ID = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_TELEGRAM_CHAT_ID = new StringConfigKey( "notificator.telegram.chatId", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Telegram notification send location message. */ - public static final ConfigKey NOTIFICATOR_TELEGRAM_SEND_LOCATION = new ConfigKey<>( + public static final ConfigKey NOTIFICATOR_TELEGRAM_SEND_LOCATION = new BooleanConfigKey( "notificator.telegram.sendLocation", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Maximum time period for reports in seconds. Can be useful to prevent users to request unreasonably long reports. * By default there is no limit. */ - public static final ConfigKey REPORT_PERIOD_LIMIT = new ConfigKey<>( + public static final ConfigKey REPORT_PERIOD_LIMIT = new LongConfigKey( "report.periodLimit", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Trips less than minimal duration and minimal distance are ignored. 300 seconds and 500 meters are default. */ - public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DISTANCE = new ConfigKey<>( + public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DISTANCE = new LongConfigKey( "report.trip.minimalTripDistance", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 500L); /** * Trips less than minimal duration and minimal distance are ignored. 300 seconds and 500 meters are default. */ - public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DURATION = new ConfigKey<>( + public static final ConfigKey REPORT_TRIP_MINIMAL_TRIP_DURATION = new LongConfigKey( "report.trip.minimalTripDuration", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 300L); /** * Parking less than minimal duration does not cut trip. Default 300 seconds. */ - public static final ConfigKey REPORT_TRIP_MINIMAL_PARKING_DURATION = new ConfigKey<>( + public static final ConfigKey REPORT_TRIP_MINIMAL_PARKING_DURATION = new LongConfigKey( "report.trip.minimalParkingDuration", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 300L); /** * Gaps of more than specified time are counted as stops. Default value is one hour. */ - public static final ConfigKey REPORT_TRIP_MINIMAL_NO_DATA_DURATION = new ConfigKey<>( + public static final ConfigKey REPORT_TRIP_MINIMAL_NO_DATA_DURATION = new LongConfigKey( "report.trip.minimalNoDataDuration", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), 3600L); /** * Flag to enable ignition use for trips calculation. */ - public static final ConfigKey REPORT_TRIP_USE_IGNITION = new ConfigKey<>( + public static final ConfigKey REPORT_TRIP_USE_IGNITION = new BooleanConfigKey( "report.trip.useIgnition", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to enable or disable position filtering. */ - public static final ConfigKey FILTER_ENABLE = new ConfigKey<>( + public static final ConfigKey FILTER_ENABLE = new BooleanConfigKey( "filter.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter invalid (valid field is set to false) positions. */ - public static final ConfigKey FILTER_INVALID = new ConfigKey<>( + public static final ConfigKey FILTER_INVALID = new BooleanConfigKey( "filter.invalid", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter zero coordinates. Zero latitude and longitude are theoretically valid values, but it practice it usually * indicates invalid GPS data. */ - public static final ConfigKey FILTER_ZERO = new ConfigKey<>( + public static final ConfigKey FILTER_ZERO = new BooleanConfigKey( "filter.zero", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter duplicate records (duplicates are detected by time value). */ - public static final ConfigKey FILTER_DUPLICATE = new ConfigKey<>( + public static final ConfigKey FILTER_DUPLICATE = new BooleanConfigKey( "filter.duplicate", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter records with fix time in future. The values is specified in seconds. Records that have fix time more than * specified number of seconds later than current server time would be filtered out. */ - public static final ConfigKey FILTER_FUTURE = new ConfigKey<>( + public static final ConfigKey FILTER_FUTURE = new LongConfigKey( "filter.future", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter positions with accuracy less than specified value in meters. */ - public static final ConfigKey FILTER_ACCURACY = new ConfigKey<>( + public static final ConfigKey FILTER_ACCURACY = new IntegerConfigKey( "filter.accuracy", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter cell and wifi locations that are coming from geolocation provider. */ - public static final ConfigKey FILTER_APPROXIMATE = new ConfigKey<>( + public static final ConfigKey FILTER_APPROXIMATE = new BooleanConfigKey( "filter.approximate", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter positions with exactly zero speed values. */ - public static final ConfigKey FILTER_STATIC = new ConfigKey<>( + public static final ConfigKey FILTER_STATIC = new BooleanConfigKey( "filter.static", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter records by distance. The values is specified in meters. If the new position is less far than this value * from the last one it gets filtered out. */ - public static final ConfigKey FILTER_DISTANCE = new ConfigKey<>( + public static final ConfigKey FILTER_DISTANCE = new IntegerConfigKey( "filter.distance", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if Position @@ -938,16 +1010,16 @@ public final class Keys { * * Tip: Shouldn't be too low. Start testing with values at about 25000. */ - public static final ConfigKey FILTER_MAX_SPEED = new ConfigKey<>( + public static final ConfigKey FILTER_MAX_SPEED = new IntegerConfigKey( "filter.maxSpeed", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Filter position if time from previous position is less than specified value in seconds. */ - public static final ConfigKey FILTER_MIN_PERIOD = new ConfigKey<>( + public static final ConfigKey FILTER_MIN_PERIOD = new IntegerConfigKey( "filter.minPeriod", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * If false, the server expects all locations to come sequentially (for each device). Filter checks for duplicates, @@ -957,262 +1029,271 @@ public final class Keys { * Filter checks for duplicates, distance, speed, or time period against the preceding Position's. * Important: setting to true can cause potential performance issues. */ - public static final ConfigKey FILTER_RELATIVE = new ConfigKey<>( + public static final ConfigKey FILTER_RELATIVE = new BooleanConfigKey( "filter.relative", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Time limit for the filtering in seconds. If the time difference between the last position was received by server * and a new position is received by server is more than this limit, the new position will not be filtered out. */ - public static final ConfigKey FILTER_SKIP_LIMIT = new ConfigKey<>( + public static final ConfigKey FILTER_SKIP_LIMIT = new LongConfigKey( "filter.skipLimit", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable attributes skipping. Attribute skipping can be enabled in the config or device attributes. * If position contains any attribute mentioned in "filter.skipAttributes" config key, position is not filtered out. */ - public static final ConfigKey FILTER_SKIP_ATTRIBUTES_ENABLE = new ConfigKey<>( + public static final ConfigKey FILTER_SKIP_ATTRIBUTES_ENABLE = new BooleanConfigKey( "filter.skipAttributes.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); + + /** + * Attribute skipping can be enabled in the config or device attributes. + * If position contains any attribute mentioned in "filter.skipAttributes" config key, position is not filtered out. + */ + public static final ConfigKey FILTER_SKIP_ATTRIBUTES = new StringConfigKey( + "filter.skipAttributes", + List.of(KeyType.CONFIG, KeyType.DEVICE), + ""); /** * Override device time. Possible values are 'deviceTime' and 'serverTime' */ - public static final ConfigKey TIME_OVERRIDE = new ConfigKey<>( + public static final ConfigKey TIME_OVERRIDE = new StringConfigKey( "time.override", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * List of protocols for overriding time. If not specified override is applied globally. List consist of protocol * names that can be separated by comma or single space character. */ - public static final ConfigKey TIME_PROTOCOLS = new ConfigKey<>( + public static final ConfigKey TIME_PROTOCOLS = new StringConfigKey( "time.protocols", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * 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<>( + public static final ConfigKey COORDINATES_FILTER = new BooleanConfigKey( "coordinates.filter", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Distance in meters. Distances below this value gets handled like explained in 'coordinates.filter'. */ - public static final ConfigKey COORDINATES_MIN_ERROR = new ConfigKey<>( + public static final ConfigKey COORDINATES_MIN_ERROR = new IntegerConfigKey( "coordinates.minError", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Distance in meters. Distances above this value gets handled like explained in 'coordinates.filter', but only if * Position is also marked as 'invalid'. */ - public static final ConfigKey COORDINATES_MAX_ERROR = new ConfigKey<>( + public static final ConfigKey COORDINATES_MAX_ERROR = new IntegerConfigKey( "coordinates.maxError", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable to save device IP addresses information. Disabled by default. */ - public static final ConfigKey PROCESSING_REMOTE_ADDRESS_ENABLE = new ConfigKey<>( + public static final ConfigKey PROCESSING_REMOTE_ADDRESS_ENABLE = new BooleanConfigKey( "processing.remoteAddress.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable copying of missing attributes from last position to the current one. Might be useful if device doesn't * send some values in every message. */ - public static final ConfigKey PROCESSING_COPY_ATTRIBUTES_ENABLE = new ConfigKey<>( + public static final ConfigKey PROCESSING_COPY_ATTRIBUTES_ENABLE = new BooleanConfigKey( "processing.copyAttributes.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enable computed attributes processing. */ - public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new ConfigKey<>( + public static final ConfigKey PROCESSING_COMPUTED_ATTRIBUTES_DEVICE_ATTRIBUTES = new BooleanConfigKey( "processing.computedAttributes.deviceAttributes", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to enable or disable reverse geocoder. */ - public static final ConfigKey GEOCODER_ENABLE = new ConfigKey<>( + public static final ConfigKey GEOCODER_ENABLE = new BooleanConfigKey( "geocoder.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Reverse geocoder type. Check reverse geocoding documentation for more info. By default (if the value is not * specified) server uses Google API. */ - public static final ConfigKey GEOCODER_TYPE = new ConfigKey<>( + public static final ConfigKey GEOCODER_TYPE = new StringConfigKey( "geocoder.type", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Geocoder server URL. Applicable only to Nominatim and Gisgraphy providers. */ - public static final ConfigKey GEOCODER_URL = new ConfigKey<>( + public static final ConfigKey GEOCODER_URL = new StringConfigKey( "geocoder.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * App id for use with Here provider. */ - public static final ConfigKey GEOCODER_ID = new ConfigKey<>( + public static final ConfigKey GEOCODER_ID = new StringConfigKey( "geocoder.id", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Provider API key. Most providers require API keys. */ - public static final ConfigKey GEOCODER_KEY = new ConfigKey<>( + public static final ConfigKey GEOCODER_KEY = new StringConfigKey( "geocoder.key", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Language parameter for providers that support localization (e.g. Google and Nominatim). */ - public static final ConfigKey GEOCODER_LANGUAGE = new ConfigKey<>( + public static final ConfigKey GEOCODER_LANGUAGE = new StringConfigKey( "geocoder.language", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Address format string. Default value is %h %r, %t, %s, %c. See AddressFormat for more info. */ - public static final ConfigKey GEOCODER_FORMAT = new ConfigKey<>( + public static final ConfigKey GEOCODER_FORMAT = new StringConfigKey( "geocoder.format", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Cache size for geocoding results. */ - public static final ConfigKey GEOCODER_CACHE_SIZE = new ConfigKey<>( + public static final ConfigKey GEOCODER_CACHE_SIZE = new IntegerConfigKey( "geocoder.cacheSize", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Disable automatic reverse geocoding requests for all positions. */ - public static final ConfigKey GEOCODER_IGNORE_POSITIONS = new ConfigKey<>( + public static final ConfigKey GEOCODER_IGNORE_POSITIONS = new BooleanConfigKey( "geocoder.ignorePositions", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to apply reverse geocoding to invalid positions. */ - public static final ConfigKey GEOCODER_PROCESS_INVALID_POSITIONS = new ConfigKey<>( + public static final ConfigKey GEOCODER_PROCESS_INVALID_POSITIONS = new BooleanConfigKey( "geocoder.processInvalidPositions", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Optional parameter to specify minimum distance for new reverse geocoding request. If distance is less than * specified value (in meters), then Traccar will reuse last known address. */ - public static final ConfigKey GEOCODER_REUSE_DISTANCE = new ConfigKey<>( + public static final ConfigKey GEOCODER_REUSE_DISTANCE = new IntegerConfigKey( "geocoder.reuseDistance", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Perform geocoding when preparing reports and sending notifications. */ - public static final ConfigKey GEOCODER_ON_REQUEST = new ConfigKey<>( + public static final ConfigKey GEOCODER_ON_REQUEST = new BooleanConfigKey( "geocoder.onRequest", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to enable LBS location resolution. Some devices send cell towers information and WiFi point when GPS * location is not available. Traccar can determine coordinates based on that information using third party * services. Default value is false. */ - public static final ConfigKey GEOLOCATION_ENABLE = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_ENABLE = new BooleanConfigKey( "geolocation.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Provider to use for LBS location. Available options: google, mozilla and opencellid. By default opencellid is * used. You have to supply a key that you get from corresponding provider. For more information see LBS geolocation * documentation. */ - public static final ConfigKey GEOLOCATION_TYPE = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_TYPE = new StringConfigKey( "geolocation.type", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Geolocation provider API URL address. Not required for most providers. */ - public static final ConfigKey GEOLOCATION_URL = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_URL = new StringConfigKey( "geolocation.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Provider API key. OpenCellID service requires API key. */ - public static final ConfigKey GEOLOCATION_KEY = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_KEY = new StringConfigKey( "geolocation.key", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to apply geolocation to invalid positions. */ - public static final ConfigKey GEOLOCATION_PROCESS_INVALID_POSITIONS = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_PROCESS_INVALID_POSITIONS = new BooleanConfigKey( "geolocation.processInvalidPositions", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Default MCC value to use if device doesn't report MCC. */ - public static final ConfigKey GEOLOCATION_MCC = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_MCC = new IntegerConfigKey( "geolocation.mcc", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Default MNC value to use if device doesn't report MNC. */ - public static final ConfigKey GEOLOCATION_MNC = new ConfigKey<>( + public static final ConfigKey GEOLOCATION_MNC = new IntegerConfigKey( "geolocation.mnc", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Boolean flag to enable speed limit API to get speed limit values depending on location. Default value is false. */ - public static final ConfigKey SPEED_LIMIT_ENABLE = new ConfigKey<>( + public static final ConfigKey SPEED_LIMIT_ENABLE = new BooleanConfigKey( "speedLimit.enable", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Provider to use for speed limit. Available options: overpass. By default overpass is used. */ - public static final ConfigKey SPEED_LIMIT_TYPE = new ConfigKey<>( + public static final ConfigKey SPEED_LIMIT_TYPE = new StringConfigKey( "speedLimit.type", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Speed limit provider API URL address. */ - public static final ConfigKey SPEED_LIMIT_URL = new ConfigKey<>( + public static final ConfigKey SPEED_LIMIT_URL = new StringConfigKey( "speedLimit.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Override latitude sign / hemisphere. Useful in cases where value is incorrect because of device bug. Value can be * N for North or S for South. */ - public static final ConfigKey LOCATION_LATITUDE_HEMISPHERE = new ConfigKey<>( + public static final ConfigKey LOCATION_LATITUDE_HEMISPHERE = new StringConfigKey( "location.latitudeHemisphere", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Override longitude sign / hemisphere. Useful in cases where value is incorrect because of device bug. Value can * be E for East or W for West. */ - public static final ConfigKey LOCATION_LONGITUDE_HEMISPHERE = new ConfigKey<>( + public static final ConfigKey LOCATION_LONGITUDE_HEMISPHERE = new StringConfigKey( "location.longitudeHemisphere", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Jetty Request Log Path. @@ -1220,112 +1301,112 @@ public final class Keys { * over the file. * Example: ./logs/jetty-yyyy_mm_dd.request.log */ - public static final ConfigKey WEB_REQUEST_LOG_PATH = new ConfigKey<>( + public static final ConfigKey WEB_REQUEST_LOG_PATH = new StringConfigKey( "web.requestLog.path", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Set the number of days before rotated request log files are deleted. */ - public static final ConfigKey WEB_REQUEST_LOG_RETAIN_DAYS = new ConfigKey<>( + public static final ConfigKey WEB_REQUEST_LOG_RETAIN_DAYS = new IntegerConfigKey( "web.requestLog.retainDays", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Disable systemd health checks. */ - public static final ConfigKey WEB_DISABLE_HEALTH_CHECK = new ConfigKey<>( + public static final ConfigKey WEB_DISABLE_HEALTH_CHECK = new BooleanConfigKey( "web.disableHealthCheck", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Sets SameSite cookie attribute value. * Supported options: Lax, Strict, None. */ - public static final ConfigKey WEB_SAME_SITE_COOKIE = new ConfigKey<>( + public static final ConfigKey WEB_SAME_SITE_COOKIE = new StringConfigKey( "web.sameSiteCookie", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Enables persisting Jetty session to the database */ - public static final ConfigKey WEB_PERSIST_SESSION = new ConfigKey<>( + public static final ConfigKey WEB_PERSIST_SESSION = new BooleanConfigKey( "web.persistSession", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Public URL for the web app. Used for notification and report link. * * If not provided, Traccar will attempt to get a URL from the server IP address, but it might be a local address. */ - public static final ConfigKey WEB_URL = new ConfigKey<>( + public static final ConfigKey WEB_URL = new StringConfigKey( "web.url", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Output logging to the standard terminal output instead of a log file. */ - public static final ConfigKey LOGGER_CONSOLE = new ConfigKey<>( + public static final ConfigKey LOGGER_CONSOLE = new BooleanConfigKey( "logger.console", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Log executed SQL queries. */ - public static final ConfigKey LOGGER_QUERIES = new ConfigKey<>( + public static final ConfigKey LOGGER_QUERIES = new BooleanConfigKey( "logger.queries", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Log file name. For rotating logs, a date is added at the end of the file name for non-current logs. */ - public static final ConfigKey LOGGER_FILE = new ConfigKey<>( + public static final ConfigKey LOGGER_FILE = new StringConfigKey( "logger.file", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Logging level. Default value is 'info'. * Available options: off, severe, warning, info, config, fine, finer, finest, all. */ - public static final ConfigKey LOGGER_LEVEL = new ConfigKey<>( + public static final ConfigKey LOGGER_LEVEL = new StringConfigKey( "logger.level", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Print full exception traces. Useful for debugging. By default shortened traces are logged. */ - public static final ConfigKey LOGGER_FULL_STACK_TRACES = new ConfigKey<>( + public static final ConfigKey LOGGER_FULL_STACK_TRACES = new BooleanConfigKey( "logger.fullStackTraces", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Create a new log file daily. Helps with log management. For example, downloading and cleaning logs. Enabled by * default. */ - public static final ConfigKey LOGGER_ROTATE = new ConfigKey<>( + public static final ConfigKey LOGGER_ROTATE = new BooleanConfigKey( "logger.rotate", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * A list of position attributes to log. */ - public static final ConfigKey LOGGER_ATTRIBUTES = new ConfigKey<>( + public static final ConfigKey LOGGER_ATTRIBUTES = new StringConfigKey( "logger.attributes", - Collections.singletonList(KeyType.CONFIG), + List.of(KeyType.CONFIG), "time,position,speed,course,accuracy,result"); /** * Multicast address for broadcasting synchronization events. */ - public static final ConfigKey BROADCAST_ADDRESS = new ConfigKey<>( + public static final ConfigKey BROADCAST_ADDRESS = new StringConfigKey( "broadcast.address", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); /** * Multicast port for broadcasting synchronization events. */ - public static final ConfigKey BROADCAST_PORT = new ConfigKey<>( + public static final ConfigKey BROADCAST_PORT = new IntegerConfigKey( "broadcast.port", - Collections.singletonList(KeyType.CONFIG)); + List.of(KeyType.CONFIG)); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 81043fd7a..a3e04f920 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -73,34 +73,6 @@ public class DeviceManager extends BaseObjectManager implements Identity refreshLastPositions(); } - @Override - public Device addUnknownDevice(String uniqueId) { - Device device = new Device(); - device.setName(uniqueId); - device.setUniqueId(uniqueId); - device.setCategory(Context.getConfig().getString(Keys.DATABASE_REGISTER_UNKNOWN_DEFAULT_CATEGORY)); - - long defaultGroupId = Context.getConfig().getLong(Keys.DATABASE_REGISTER_UNKNOWN_DEFAULT_GROUP_ID); - if (defaultGroupId != 0) { - device.setGroupId(defaultGroupId); - } - - try { - addItem(device); - - LOGGER.info("Automatically registered device " + uniqueId); - - if (defaultGroupId != 0) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - } - - return device; - } catch (StorageException e) { - LOGGER.warn("Automatic device registration error", e); - return null; - } - } - public void updateDeviceCache(boolean force) { long lastUpdate = devicesLastUpdate.get(); if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) @@ -316,35 +288,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return result != null ? (String) result : defaultValue; } - @Override - 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(); - } - return defaultValue; - } - - @Override - public long lookupAttributeLong( - 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(); - } - return defaultValue; - } - - public double lookupAttributeDouble( - 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 lookupServer, boolean lookupConfig) { Object result = null; Device device = getById(deviceId); diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index ee386fdfd..10a64ebd9 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -20,8 +20,6 @@ import org.traccar.model.Position; public interface IdentityManager { - Device addUnknownDevice(String uniqueId); - Device getById(long id); Device getByUniqueId(String uniqueId) throws Exception; @@ -38,13 +36,4 @@ public interface IdentityManager { String lookupAttributeString( long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig); - int lookupAttributeInteger( - long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig); - - long lookupAttributeLong( - long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig); - - double lookupAttributeDouble( - long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig); - } diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 0511ec98b..00cbf92a0 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -21,11 +21,18 @@ import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.DataManager; -import org.traccar.database.IdentityManager; import org.traccar.helper.UnitsConverter; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Limit; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.Date; @@ -50,11 +57,11 @@ public class FilterHandler extends BaseDataHandler { private final long skipLimit; private final boolean skipAttributes; - private final IdentityManager identityManager; - private final DataManager dataManager; + private final CacheManager cacheManager; + private final Storage storage; @Inject - public FilterHandler(Config config, IdentityManager identityManager, DataManager dataManager) { + public FilterHandler(Config config, CacheManager cacheManager, Storage storage) { enabled = config.getBoolean(Keys.FILTER_ENABLE); filterInvalid = config.getBoolean(Keys.FILTER_INVALID); filterZero = config.getBoolean(Keys.FILTER_ZERO); @@ -69,8 +76,18 @@ public class FilterHandler extends BaseDataHandler { filterRelative = config.getBoolean(Keys.FILTER_RELATIVE); skipLimit = config.getLong(Keys.FILTER_SKIP_LIMIT) * 1000; skipAttributes = config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE); - this.identityManager = identityManager; - this.dataManager = dataManager; + this.cacheManager = cacheManager; + this.storage = storage; + } + + private Position getPrecedingPosition(long deviceId, Date date) throws StorageException { + return storage.getObject(Position.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Compare("fixTime", "<=", "time", date)), + new Order(true, "fixTime"), + new Limit(1))); } private boolean filterInvalid(Position position) { @@ -144,9 +161,8 @@ public class FilterHandler extends BaseDataHandler { private boolean skipAttributes(Position position) { if (skipAttributes) { - String attributesString = identityManager.lookupAttributeString( - position.getDeviceId(), "filter.skipAttributes", "", false, true); - for (String attribute : attributesString.split("[ ,]")) { + String string = AttributeUtil.lookup(cacheManager, Keys.FILTER_SKIP_ATTRIBUTES, position.getDeviceId()); + for (String attribute : string.split("[ ,]")) { if (position.getAttributes().containsKey(attribute)) { return true; } @@ -183,13 +199,13 @@ public class FilterHandler extends BaseDataHandler { if (filterRelative) { try { Date newFixTime = position.getFixTime(); - preceding = dataManager.getPrecedingPosition(deviceId, newFixTime); + preceding = getPrecedingPosition(deviceId, newFixTime); } catch (StorageException e) { LOGGER.warn("Error retrieving preceding position; fallbacking to last received position.", e); - preceding = getLastReceivedPosition(deviceId); + preceding = cacheManager.getPosition(deviceId); } } else { - preceding = getLastReceivedPosition(deviceId); + preceding = cacheManager.getPosition(deviceId); } if (filterDuplicate(position, preceding) && !skipLimit(position, preceding) && !skipAttributes(position)) { filterType.append("Duplicate "); @@ -209,7 +225,7 @@ public class FilterHandler extends BaseDataHandler { } if (filterType.length() > 0) { - String uniqueId = identityManager.getById(deviceId).getUniqueId(); + String uniqueId = cacheManager.getObject(Device.class, deviceId).getUniqueId(); LOGGER.info("Position filtered by {}filters from device: {}", filterType, uniqueId); return true; } @@ -217,10 +233,6 @@ public class FilterHandler extends BaseDataHandler { return false; } - private Position getLastReceivedPosition(long deviceId) { - return identityManager.getLastPosition(deviceId); - } - @Override protected Position handlePosition(Position position) { if (enabled && filter(position)) { diff --git a/src/main/java/org/traccar/handler/HemisphereHandler.java b/src/main/java/org/traccar/handler/HemisphereHandler.java index 2e3ed9d91..f760457a3 100644 --- a/src/main/java/org/traccar/handler/HemisphereHandler.java +++ b/src/main/java/org/traccar/handler/HemisphereHandler.java @@ -39,7 +39,7 @@ public class HemisphereHandler extends BaseDataHandler { latitudeFactor = -1; } } - String longitudeHemisphere = config.getString(Keys.LOCATION_LATITUDE_HEMISPHERE); + String longitudeHemisphere = config.getString(Keys.LOCATION_LONGITUDE_HEMISPHERE); if (longitudeHemisphere != null) { if (longitudeHemisphere.equalsIgnoreCase("E")) { longitudeFactor = 1; diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java index 7849abff9..2d105af3e 100644 --- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java @@ -16,10 +16,13 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import java.util.Collections; @@ -28,31 +31,28 @@ import java.util.Map; @ChannelHandler.Sharable public class FuelDropEventHandler extends BaseEventHandler { - public static final String ATTRIBUTE_FUEL_DROP_THRESHOLD = "fuelDropThreshold"; - - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public FuelDropEventHandler(IdentityManager identityManager) { - this.identityManager = identityManager; + public FuelDropEventHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Map analyzePosition(Position position) { - Device device = identityManager.getById(position.getDeviceId()); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); if (device == null) { return null; } - if (!identityManager.isLatestPosition(position)) { + if (!PositionUtil.isLatest(cacheManager, position)) { return null; } - double fuelDropThreshold = identityManager - .lookupAttributeDouble(device.getId(), ATTRIBUTE_FUEL_DROP_THRESHOLD, 0, true, false); - + double fuelDropThreshold = AttributeUtil.lookup( + cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); if (fuelDropThreshold > 0) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (position.getAttributes().containsKey(Position.KEY_FUEL_LEVEL) && lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_FUEL_LEVEL)) { @@ -60,7 +60,6 @@ public class FuelDropEventHandler extends BaseEventHandler { - position.getDouble(Position.KEY_FUEL_LEVEL); if (drop >= fuelDropThreshold) { Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position); - event.set(ATTRIBUTE_FUEL_DROP_THRESHOLD, fuelDropThreshold); return Collections.singletonMap(event, position); } } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 45bb13be5..6de56d11e 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -23,6 +23,8 @@ import io.netty.channel.ChannelHandler; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceManager; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.session.DeviceState; import org.traccar.model.Event; @@ -36,7 +38,6 @@ import javax.inject.Inject; public class OverspeedEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_SPEED = "speed"; - public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit"; private final DeviceManager deviceManager; private final CacheManager cacheManager; @@ -58,7 +59,7 @@ public class OverspeedEventHandler extends BaseEventHandler { Position position = deviceState.getOverspeedPosition(); Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); event.set(ATTRIBUTE_SPEED, deviceState.getOverspeedPosition().getSpeed()); - event.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); + event.set(Position.KEY_SPEED_LIMIT, speedLimit); event.setGeofenceId(deviceState.getOverspeedGeofenceId()); deviceState.setOverspeedState(notRepeat); deviceState.setOverspeedPosition(null); @@ -115,15 +116,15 @@ public class OverspeedEventHandler extends BaseEventHandler { protected Map analyzePosition(Position position) { long deviceId = position.getDeviceId(); - Device device = deviceManager.getById(deviceId); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); if (device == null) { return null; } - if (!deviceManager.isLatestPosition(position) || !position.getValid()) { + if (!PositionUtil.isLatest(cacheManager, position) || !position.getValid()) { return null; } - double speedLimit = deviceManager.lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, true, false); + double speedLimit = AttributeUtil.lookup(cacheManager, Keys.EVENT_OVERSPEED_LIMIT, deviceId); double positionSpeedLimit = position.getDouble(Position.KEY_SPEED_LIMIT); if (positionSpeedLimit > 0) { @@ -137,7 +138,7 @@ public class OverspeedEventHandler extends BaseEventHandler { for (long geofenceId : device.getGeofenceIds()) { Geofence geofence = cacheManager.getObject(Geofence.class, geofenceId); if (geofence != null) { - double currentSpeedLimit = geofence.getDouble(ATTRIBUTE_SPEED_LIMIT); + double currentSpeedLimit = geofence.getDouble(Keys.EVENT_OVERSPEED_LIMIT.getKey()); if (currentSpeedLimit > 0 && geofenceSpeedLimit == 0 || preferLowest && currentSpeedLimit < geofenceSpeedLimit || !preferLowest && currentSpeedLimit > geofenceSpeedLimit) { diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java new file mode 100644 index 000000000..5b3fc1cbe --- /dev/null +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -0,0 +1,72 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper.model; + +import org.traccar.config.ConfigKey; +import org.traccar.config.KeyType; +import org.traccar.model.Device; +import org.traccar.model.Group; +import org.traccar.session.cache.CacheManager; + +public final class AttributeUtil { + + private AttributeUtil() { + } + + @SuppressWarnings({ "deprecation", "unchecked" }) + public static T lookup(CacheManager cacheManager, ConfigKey key, long deviceId) { + Device device = cacheManager.getObject(Device.class, deviceId); + Object result = device.getAttributes().get(key.getKey()); + long groupId = device.getGroupId(); + while (result == null && groupId > 0) { + Group group = cacheManager.getObject(Group.class, groupId); + if (group != null) { + result = group.getAttributes().get(key.getKey()); + } + } + if (result == null && key.hasType(KeyType.SERVER)) { + result = cacheManager.getServer().getAttributes().get(key.getKey()); + } + if (result == null && key.hasType(KeyType.CONFIG)) { + result = cacheManager.getConfig().getString(key.getKey()); + } + + if (result != null) { + Class valueClass = key.getValueClass(); + if (valueClass.equals(Boolean.class)) { + return (T) (result instanceof String + ? Boolean.parseBoolean((String) result) + : result); + } else if (valueClass.equals(Integer.class)) { + return (T) (Object) (result instanceof String + ? Integer.parseInt((String) result) + : ((Number) result).intValue()); + } else if (valueClass.equals(Long.class)) { + return (T) (Object) (result instanceof String + ? Long.parseLong((String) result) + : ((Number) result).longValue()); + } else if (valueClass.equals(Double.class)) { + return (T) (Object) (result instanceof String + ? Double.parseDouble((String) result) + : ((Number) result).doubleValue()); + } else { + return (T) result; + } + } + return key.getDefaultValue(); + } + +} diff --git a/src/main/java/org/traccar/model/CellTower.java b/src/main/java/org/traccar/model/CellTower.java index af33b1f5c..16a28ea79 100644 --- a/src/main/java/org/traccar/model/CellTower.java +++ b/src/main/java/org/traccar/model/CellTower.java @@ -38,7 +38,7 @@ public class CellTower { } public static CellTower fromLacCid(Config config, int lac, long cid) { - return from(config.getInteger(Keys.GEOLOCATION_MCC), config.getInteger(Keys.GEOLOCATION_MCC), lac, cid); + return from(config.getInteger(Keys.GEOLOCATION_MCC), config.getInteger(Keys.GEOLOCATION_MNC), lac, cid); } public static CellTower fromCidLac(Config config, long cid, int lac) { diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index 0ff668fa8..aa23bfac5 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 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@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,8 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DataConverter; @@ -66,8 +68,9 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } public String[] getFormat(long deviceId) { - return getIdentityManager().lookupAttributeString( - deviceId, getProtocolName() + ".format", format, false, false).split(","); + String value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_FORMAT.withPrefix(getProtocolName()), deviceId); + return (value != null ? value : format).split(","); } public void setFormat(String format) { @@ -75,8 +78,9 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } public DateFormat getDateFormat(long deviceId) { - DateFormat dateFormat = new SimpleDateFormat(getIdentityManager().lookupAttributeString( - deviceId, getProtocolName() + ".dateFormat", this.dateFormat, false, false)); + String value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_DATE_FORMAT.withPrefix(getProtocolName()), deviceId); + DateFormat dateFormat = new SimpleDateFormat(value != null ? value : this.dateFormat); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); return dateFormat; } diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 6340def86..44ba1da38 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -20,6 +20,8 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -71,8 +73,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public int getProtocolType(long deviceId) { - return getIdentityManager().lookupAttributeInteger( - deviceId, getProtocolName() + ".protocolType", protocolType, false, true); + Integer value = AttributeUtil.lookup(getCacheManager(), Keys.PROTOCOL_TYPE, deviceId); + return value != null ? value : protocolType; } public void setHbm(boolean hbm) { @@ -80,8 +82,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isHbm(long deviceId) { - return getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".hbm", hbm, false, true); + Boolean value = AttributeUtil.lookup(getCacheManager(), Keys.PROTOCOL_HBM, deviceId); + return value != null ? value : hbm; } public void setIncludeAdc(boolean includeAdc) { @@ -89,8 +91,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeAdc(long deviceId) { - return getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeAdc", includeAdc, false, true); + Boolean value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_INCLUDE_ADC.withPrefix(getProtocolName()), deviceId); + return value != null ? value : includeAdc; } public void setIncludeRpm(boolean includeRpm) { @@ -98,8 +101,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeRpm(long deviceId) { - return getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeRpm", includeRpm, false, true); + Boolean value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_INCLUDE_RPM.withPrefix(getProtocolName()), deviceId); + return value != null ? value : includeRpm; } public void setIncludeTemp(boolean includeTemp) { @@ -107,8 +111,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } public boolean isIncludeTemp(long deviceId) { - return getIdentityManager().lookupAttributeBoolean( - deviceId, getProtocolName() + ".includeTemp", includeTemp, false, true); + Boolean value = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_INCLUDE_TEMPERATURE.withPrefix(getProtocolName()), deviceId); + return value != null ? value : includeTemp; } private Position decode9( diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 6d5fefa75..3fa467b57 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -28,6 +28,7 @@ import org.traccar.config.Keys; import org.traccar.database.NotificationManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; @@ -279,9 +280,9 @@ public class ConnectionManager { result.putAll(event); } + double speedLimit = AttributeUtil.lookup(cacheManager, Keys.EVENT_OVERSPEED_LIMIT, deviceId); event = Main.getInjector().getInstance(OverspeedEventHandler.class) - .updateOverspeedState(deviceState, Context.getDeviceManager(). - lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, true, false)); + .updateOverspeedState(deviceState, speedLimit); if (event != null) { result.putAll(event); } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 896df83e7..87384f746 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -74,6 +74,10 @@ public class CacheManager { invalidateUsers(); } + public Config getConfig() { + return config; + } + public T getObject(Class clazz, long id) { try { lock.readLock().lock(); diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 1652a6694..add423cdd 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -9,6 +9,7 @@ import org.traccar.database.StatisticsManager; import org.traccar.model.Device; import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; +import org.traccar.session.cache.CacheManager; import java.net.SocketAddress; import java.util.HashSet; @@ -16,6 +17,7 @@ import java.util.HashSet; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -23,19 +25,18 @@ import static org.mockito.Mockito.when; public class BaseTest { protected T inject(T decoder) throws Exception { - decoder.setConfig(new Config()); + var config = new Config(); + decoder.setConfig(config); var device = mock(Device.class); when(device.getId()).thenReturn(1L); var identityManager = mock(IdentityManager.class); when(identityManager.getById(anyLong())).thenReturn(device); when(identityManager.getByUniqueId(any())).thenReturn(device); - when(identityManager.lookupAttributeBoolean(anyLong(), any(), anyBoolean(), anyBoolean(), anyBoolean())) - .thenAnswer(invocation -> invocation.getArguments()[2]); - when(identityManager.lookupAttributeString(anyLong(), any(), any(), anyBoolean(), anyBoolean())) - .thenAnswer(invocation -> invocation.getArguments()[2]); - when(identityManager.lookupAttributeInteger(anyLong(), any(), anyInt(), anyBoolean(), anyBoolean())) - .thenAnswer(invocation -> invocation.getArguments()[2]); decoder.setIdentityManager(identityManager); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getConfig()).thenReturn(config); + when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); + decoder.setCacheManager(cacheManager); var connectionManager = mock(ConnectionManager.class); var uniqueIdsProvided = new HashSet(); when(connectionManager.getDeviceSession(any(), any(), any(), any())).thenAnswer(invocation -> { diff --git a/src/test/java/org/traccar/handler/FilterHandlerTest.java b/src/test/java/org/traccar/handler/FilterHandlerTest.java index 10d6768cf..a1102da88 100644 --- a/src/test/java/org/traccar/handler/FilterHandlerTest.java +++ b/src/test/java/org/traccar/handler/FilterHandlerTest.java @@ -5,15 +5,16 @@ import org.junit.Test; import org.traccar.BaseTest; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.DataManager; -import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import java.util.Date; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -26,9 +27,9 @@ public class FilterHandlerTest extends BaseTest { public void passingHandler() { var config = mock(Config.class); when(config.getBoolean(Keys.FILTER_ENABLE)).thenReturn(true); - var identityManager = mock(IdentityManager.class); - var dataManager = mock(DataManager.class); - passingHandler = new FilterHandler(config, identityManager, dataManager); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getConfig()).thenReturn(config); + passingHandler = new FilterHandler(config, cacheManager, null); } @Before @@ -45,11 +46,11 @@ public class FilterHandlerTest extends BaseTest { when(config.getInteger(Keys.FILTER_MAX_SPEED)).thenReturn(500); when(config.getLong(Keys.FILTER_SKIP_LIMIT)).thenReturn(10L); when(config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE)).thenReturn(true); - var identityManager = mock(IdentityManager.class); - when(identityManager.lookupAttributeString(0, "filter.skipAttributes", "", false, true)).thenReturn("alarm,result"); - when(identityManager.getById(0)).thenReturn(mock(Device.class)); - var dataManager = mock(DataManager.class); - filteringHandler = new FilterHandler(config, identityManager, dataManager); + when(config.getString(Keys.FILTER_SKIP_ATTRIBUTES.getKey())).thenReturn("alarm,result"); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getConfig()).thenReturn(config); + when(cacheManager.getObject(any(), anyLong())).thenReturn(mock(Device.class)); + filteringHandler = new FilterHandler(config, cacheManager, null); } private Position createPosition(Date time, boolean valid, double speed) { diff --git a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java index 9e86031e8..46e142935 100644 --- a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java @@ -61,7 +61,7 @@ public class OverspeedEventHandlerTest extends BaseTest { Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); assertEquals(50, event.getDouble("speed"), 0.1); - assertEquals(40, event.getDouble(OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT), 0.1); + assertEquals(40, event.getDouble("speedLimit"), 0.1); assertEquals(geofenceId, event.getGeofenceId()); assertEquals(notRepeat, deviceState.getOverspeedState()); -- cgit v1.2.3 From 22bd8bcc80b850dc2308be50cf2886c39b0655da Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 10:08:52 -0700 Subject: Refactor device password --- src/main/java/org/traccar/BaseProtocolEncoder.java | 20 +++++++++++++++++--- src/main/java/org/traccar/config/Keys.java | 7 +++++++ .../java/org/traccar/database/DeviceManager.java | 18 ------------------ .../java/org/traccar/database/IdentityManager.java | 2 -- .../org/traccar/helper/model/AttributeUtil.java | 21 +++++++++++++++++++++ .../org/traccar/protocol/Gt06ProtocolEncoder.java | 5 +++-- .../org/traccar/protocol/LaipacProtocolDecoder.java | 5 +++-- src/test/java/org/traccar/BaseTest.java | 6 ++++-- 8 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index 10b780fc8..612d91c57 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -15,7 +15,6 @@ */ package org.traccar; -import com.google.inject.Inject; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; @@ -24,7 +23,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.database.IdentityManager; import org.traccar.helper.NetworkUtil; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; +import org.traccar.session.cache.CacheManager; + +import javax.inject.Inject; public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter { @@ -34,12 +37,23 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter private final Protocol protocol; + private CacheManager cacheManager; + private IdentityManager identityManager; public BaseProtocolEncoder(Protocol protocol) { this.protocol = protocol; } + public CacheManager getCacheManager() { + return cacheManager; + } + + @Inject + public void setCacheManager(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + public IdentityManager getIdentityManager() { return identityManager; } @@ -59,8 +73,8 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter protected void initDevicePassword(Command command, String defaultPassword) { if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { - String password = identityManager - .getDevicePassword(command.getDeviceId(), getProtocolName(), defaultPassword); + String password = AttributeUtil.getDevicePassword( + cacheManager, command.getDeviceId(), getProtocolName(), defaultPassword); command.set(Command.KEY_DEVICE_PASSWORD, password); } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 465751d38..410947079 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -69,6 +69,13 @@ public final class Keys { ".timeout", List.of(KeyType.CONFIG)); + /** + * Device password. Commonly used in some protocol for sending commands. + */ + public static final ConfigKey DEVICE_PASSWORD = new StringConfigKey( + "devicePassword", + List.of(KeyType.DEVICE)); + /** * Device password. Commonly used in some protocol for sending commands. */ diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index a3e04f920..eee19c4c2 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -99,24 +99,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - @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(Keys.PROTOCOL_DEVICE_PASSWORD.withPrefix(protocol)); - if (password != null) { - return password; - } - } - - return defaultPassword; - } - @Override public Set getAllItems() { Set result = super.getAllItems(); diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index 10a64ebd9..1897c637f 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -24,8 +24,6 @@ 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); diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java index 5b3fc1cbe..225089d5c 100644 --- a/src/main/java/org/traccar/helper/model/AttributeUtil.java +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -15,8 +15,11 @@ */ package org.traccar.helper.model; +import org.traccar.Context; import org.traccar.config.ConfigKey; import org.traccar.config.KeyType; +import org.traccar.config.Keys; +import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.session.cache.CacheManager; @@ -69,4 +72,22 @@ public final class AttributeUtil { return key.getDefaultValue(); } + public static String getDevicePassword( + CacheManager cacheManager, long deviceId, String protocol, String defaultPassword) { + + String password = lookup(cacheManager, Keys.DEVICE_PASSWORD, deviceId); + if (password != null) { + return password; + } + + if (protocol != null) { + password = cacheManager.getConfig().getString(Keys.PROTOCOL_DEVICE_PASSWORD.withPrefix(protocol)); + if (password != null) { + return password; + } + } + + return defaultPassword; + } + } diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index 3ed828fc7..569f4a809 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Protocol; import org.traccar.helper.Checksum; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import java.nio.charset.StandardCharsets; @@ -68,8 +69,8 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { boolean alternative = getIdentityManager().lookupAttributeBoolean( command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); - String password = getIdentityManager() - .getDevicePassword(command.getDeviceId(), getProtocolName(), "123456"); + String password = AttributeUtil.getDevicePassword( + getCacheManager(), command.getDeviceId(), getProtocolName(), "123456"); switch (command.getType()) { case Command.TYPE_ENGINE_STOP: diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index c55c0624d..e9570ee11 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -17,6 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -252,8 +253,8 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { sendAcknowledge(status, event, checksum, channel, remoteAddress); - String devicePassword = getIdentityManager() - .getDevicePassword(deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); + String devicePassword = AttributeUtil.getDevicePassword( + getCacheManager(), deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD); sendEventResponse(event, devicePassword, channel, remoteAddress); } diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index add423cdd..54035553f 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -66,9 +66,11 @@ public class BaseTest { var device = mock(Device.class); when(device.getId()).thenReturn(1L); when(device.getUniqueId()).thenReturn("123456789012345"); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getConfig()).thenReturn(mock(Config.class)); + when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); + encoder.setCacheManager(cacheManager); var identityManager = mock(IdentityManager.class); - when(identityManager.getDevicePassword(anyLong(), any(), any())) - .thenAnswer(invocation -> invocation.getArguments()[2]); when(identityManager.getById(anyLong())).thenReturn(device); when(identityManager.getByUniqueId(any())).thenReturn(device); encoder.setIdentityManager(identityManager); -- cgit v1.2.3 From 97a189c51817a6b1d7a86aece8a91ff378488799 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 10:27:24 -0700 Subject: Refactor attribute lookup --- src/main/java/org/traccar/config/Keys.java | 35 +++++++++++++++- .../java/org/traccar/database/DeviceManager.java | 48 ---------------------- .../java/org/traccar/database/IdentityManager.java | 8 +--- .../org/traccar/handler/CopyAttributesHandler.java | 15 +++---- .../org/traccar/protocol/Gt06ProtocolEncoder.java | 9 ++-- .../org/traccar/protocol/H02ProtocolEncoder.java | 7 +++- .../traccar/protocol/HuabaoProtocolEncoder.java | 6 ++- .../traccar/protocol/MeiligaoProtocolEncoder.java | 6 ++- .../traccar/protocol/MeitrackProtocolEncoder.java | 6 ++- .../org/traccar/protocol/T55ProtocolDecoder.java | 12 ++++-- .../org/traccar/protocol/Tk103ProtocolEncoder.java | 8 ++-- .../org/traccar/reports/StopsReportProvider.java | 3 +- .../org/traccar/reports/SummaryReportProvider.java | 3 +- .../org/traccar/reports/TripsReportProvider.java | 4 +- 14 files changed, 81 insertions(+), 89 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 410947079..5909ae517 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -124,7 +124,8 @@ public final class Keys { */ public static final ConfigSuffix PROTOCOL_ACK = new BooleanConfigSuffix( ".ack", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG, KeyType.DEVICE), + false); /** * Ignore device reported fix time. Useful in case some devices report invalid time. Currently only available for @@ -268,6 +269,22 @@ public final class Keys { "orbcomm.password", List.of(KeyType.CONFIG)); + /** + * Use alternative format for the protocol of commands. + */ + public static final ConfigSuffix PROTOCOL_ALTERNATIVE = new BooleanConfigSuffix( + ".alternative", + List.of(KeyType.CONFIG, KeyType.DEVICE), + false); + + /** + * Protocol format includes a language field. + */ + public static final ConfigSuffix PROTOCOL_LANGUAGE = new BooleanConfigSuffix( + ".language", + List.of(KeyType.CONFIG, KeyType.DEVICE), + false); + /** * Server wide connection timeout value in seconds. See protocol timeout for more information. */ @@ -944,6 +961,14 @@ public final class Keys { "report.trip.useIgnition", List.of(KeyType.CONFIG)); + /** + * Ignore odometer value reported by the device and use server-calculated total distance instead. This is useful + * if device reports invalid or zero odometer values. + */ + public static final ConfigKey REPORT_IGNORE_ODOMETER = new BooleanConfigKey( + "report.ignoreOdometer", + List.of(KeyType.CONFIG)); + /** * Boolean flag to enable or disable position filtering. */ @@ -1119,6 +1144,14 @@ public final class Keys { "processing.copyAttributes.enable", List.of(KeyType.CONFIG)); + /** + * List of attributes to copy. Attributes should be separated by a comma without any spacing. + * For example: alarm,ignition + */ + public static final ConfigKey PROCESSING_COPY_ATTRIBUTES = new StringConfigKey( + "processing.copyAttributes", + List.of(KeyType.CONFIG, KeyType.DEVICE)); + /** * Enable computed attributes processing. */ diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index eee19c4c2..86334ede8 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -253,54 +253,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return result; } - @Override - public boolean lookupAttributeBoolean( - 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; - } - return defaultValue; - } - - @Override - public String lookupAttributeString( - long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig) { - Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig); - return result != null ? (String) result : defaultValue; - } - - private Object lookupAttribute(long deviceId, String attributeName, boolean lookupServer, boolean lookupConfig) { - Object result = null; - Device device = getById(deviceId); - if (device != null) { - result = device.getAttributes().get(attributeName); - if (result == null) { - long groupId = device.getGroupId(); - while (groupId > 0) { - Group group = cacheManager.getObject(Group.class, device.getGroupId()); - if (group != null) { - result = group.getAttributes().get(attributeName); - if (result != null) { - break; - } - groupId = group.getGroupId(); - } else { - groupId = 0; - } - } - } - if (result == null && lookupServer) { - Server server = cacheManager.getServer(); - result = server.getAttributes().get(attributeName); - } - if (result == null && lookupConfig) { - result = Context.getConfig().getString(attributeName); - } - } - return result; - } - public DeviceState getDeviceState(long deviceId) { DeviceState deviceState = deviceStates.get(deviceId); if (deviceState == null) { diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index 1897c637f..5ef1c8c5e 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,10 +28,4 @@ public interface IdentityManager { boolean isLatestPosition(Position position); - boolean lookupAttributeBoolean( - long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig); - - String lookupAttributeString( - long deviceId, String attributeName, String 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 8285dcc5d..405a52ecd 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -20,8 +20,9 @@ import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @@ -29,20 +30,20 @@ import javax.inject.Inject; public class CopyAttributesHandler extends BaseDataHandler { private final boolean enabled; - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public CopyAttributesHandler(Config config, IdentityManager identityManager) { + public CopyAttributesHandler(Config config, CacheManager cacheManager) { enabled = config.getBoolean(Keys.PROCESSING_COPY_ATTRIBUTES_ENABLE); - this.identityManager = identityManager; + this.cacheManager = cacheManager; } @Override protected Position handlePosition(Position position) { if (enabled) { - String attributesString = identityManager.lookupAttributeString( - position.getDeviceId(), "processing.copyAttributes", "", false, true); - Position last = identityManager.getLastPosition(position.getDeviceId()); + String attributesString = AttributeUtil.lookup( + cacheManager, Keys.PROCESSING_COPY_ATTRIBUTES, position.getDeviceId()); + Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { for (String attribute : attributesString.split("[ ,]")) { if (last.getAttributes().containsKey(attribute) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index 569f4a809..e1c17710b 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -19,6 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.Checksum; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; @@ -33,8 +34,8 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { private ByteBuf encodeContent(long deviceId, String content) { - boolean language = getIdentityManager() - .lookupAttributeBoolean(deviceId, getProtocolName() + ".language", false, false, true); + boolean language = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_LANGUAGE.withPrefix(getProtocolName()), deviceId); ByteBuf buf = Unpooled.buffer(); @@ -66,8 +67,8 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); String password = AttributeUtil.getDevicePassword( getCacheManager(), command.getDeviceId(), getProtocolName(), "123456"); diff --git a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java index 7fca0f93e..86b8c80d4 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java @@ -18,6 +18,8 @@ package org.traccar.protocol; import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import java.util.Date; @@ -58,8 +60,9 @@ public class H02ProtocolEncoder extends StringProtocolEncoder { return formatCommand(time, uniqueId, "S20", "1", "0"); case Command.TYPE_POSITION_PERIODIC: String frequency = command.getAttributes().get(Command.KEY_FREQUENCY).toString(); - if (getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true)) { + if (AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), + command.getDeviceId())) { return formatCommand(time, uniqueId, "D1", frequency); } else { return formatCommand(time, uniqueId, "S71", "22", frequency); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java index 82cf03b51..ada7e3fba 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java @@ -19,7 +19,9 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.DataConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import java.text.SimpleDateFormat; @@ -34,8 +36,8 @@ public class HuabaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); ByteBuf id = Unpooled.wrappedBuffer( DataConverter.parseHex(getUniqueId(command.getDeviceId()))); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java index 7784ab093..21f9f8801 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -19,8 +19,10 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; import org.traccar.Protocol; +import org.traccar.config.Keys; import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import java.nio.charset.StandardCharsets; @@ -58,8 +60,8 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); int outputControlMessageType = alternative ? MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1 diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java index 799e14ea2..365dbb35a 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java @@ -17,7 +17,9 @@ package org.traccar.protocol; import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.config.Keys; import org.traccar.helper.Checksum; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; import java.util.Map; @@ -41,8 +43,8 @@ public class MeitrackProtocolEncoder extends StringProtocolEncoder { Map attributes = command.getAttributes(); - boolean alternative = getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); switch (command.getType()) { case Command.TYPE_POSITION_SINGLE: diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 3d892c021..409c7e768 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -17,6 +17,8 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -128,10 +130,12 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { private Position decodeGprmc( DeviceSession deviceSession, String sentence, SocketAddress remoteAddress, Channel channel) { - if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel) - && getIdentityManager().lookupAttributeBoolean( - deviceSession.getDeviceId(), getProtocolName() + ".ack", false, false, true)) { - channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); + if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel)) { + boolean ack = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ACK.withPrefix(getProtocolName()), deviceSession.getDeviceId()); + if (ack) { + channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress)); + } } Parser parser = new Parser(PATTERN_GPRMC, sentence); diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java index a0e9b199c..e3e1ae961 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java @@ -18,6 +18,8 @@ package org.traccar.protocol; import org.traccar.Protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; public class Tk103ProtocolEncoder extends StringProtocolEncoder { @@ -41,12 +43,12 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - boolean alternative = forceAlternative || getIdentityManager().lookupAttributeBoolean( - command.getDeviceId(), getProtocolName() + ".alternative", false, false, true); + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); initDevicePassword(command, "123456"); - if (alternative) { + if (alternative || forceAlternative) { switch (command.getType()) { case Command.TYPE_CUSTOM: return formatAlt(command, "%s", Command.KEY_DATA); diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index a63d7ee21..192d7a0f7 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -57,8 +57,7 @@ public class StopsReportProvider { } private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); + boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); return reportUtils.detectTripsAndStops( PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, StopReportItem.class); } diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 86d76b4e3..f3a9786b9 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -74,8 +74,7 @@ public class SummaryReportProvider { result.setMaxSpeed(position.getSpeed()); } } - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); + boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); result.setDistance(PositionUtil.calculateDistance(firstPosition, previousPosition, !ignoreOdometer)); result.setSpentFuel(reportUtils.calculateFuel(firstPosition, previousPosition)); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index bec4c39fd..928609b9e 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -57,9 +57,7 @@ public class TripsReportProvider { } private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { - boolean ignoreOdometer = Context.getDeviceManager() - .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true); - + boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); return reportUtils.detectTripsAndStops( PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, TripReportItem.class); } -- cgit v1.2.3 From 182656b6dc1fb5d167bb752c16ecf633add001a8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 10:37:21 -0700 Subject: Remove unused code --- src/main/java/org/traccar/Context.java | 2 - .../org/traccar/database/BaseObjectManager.java | 4 -- .../java/org/traccar/database/DeviceManager.java | 74 +--------------------- .../java/org/traccar/database/IdentityManager.java | 2 - .../org/traccar/helper/model/AttributeUtil.java | 2 - src/test/java/org/traccar/BaseTest.java | 2 - 6 files changed, 2 insertions(+), 84 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 9e8e3c521..854af97c0 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -25,7 +25,6 @@ import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.session.ConnectionManager; -import org.traccar.session.cache.CacheManager; import org.traccar.storage.Storage; public final class Context { @@ -70,7 +69,6 @@ public final class Context { deviceManager = new DeviceManager( config, - Main.getInjector().getInstance(CacheManager.class), Main.getInjector().getInstance(DataManager.class), Main.getInjector().getInstance(ConnectionManager.class)); diff --git a/src/main/java/org/traccar/database/BaseObjectManager.java b/src/main/java/org/traccar/database/BaseObjectManager.java index dd8b3bae4..c94053985 100644 --- a/src/main/java/org/traccar/database/BaseObjectManager.java +++ b/src/main/java/org/traccar/database/BaseObjectManager.java @@ -67,10 +67,6 @@ public class BaseObjectManager { return dataManager; } - protected final Class getBaseClass() { - return baseClass; - } - public T getById(long itemId) { try { readLock(); diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 86334ede8..841915f1c 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -20,14 +20,10 @@ import org.slf4j.LoggerFactory; import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.model.Command; import org.traccar.model.Device; -import org.traccar.model.Group; import org.traccar.model.Position; -import org.traccar.model.Server; import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceState; -import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import java.util.Collection; @@ -43,12 +39,9 @@ public class DeviceManager extends BaseObjectManager implements Identity private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); - private final Config config; - private final CacheManager cacheManager; private final ConnectionManager connectionManager; private final long dataRefreshDelay; - private Map devicesByUniqueId; private final AtomicLong devicesLastUpdate = new AtomicLong(); private final Map positions = new ConcurrentHashMap<>(); @@ -56,19 +49,9 @@ public class DeviceManager extends BaseObjectManager implements Identity private final Map deviceStates = new ConcurrentHashMap<>(); public DeviceManager( - Config config, CacheManager cacheManager, DataManager dataManager, ConnectionManager connectionManager) { + Config config, DataManager dataManager, ConnectionManager connectionManager) { super(dataManager, Device.class); - this.config = config; - this.cacheManager = cacheManager; this.connectionManager = connectionManager; - try { - writeLock(); - if (devicesByUniqueId == null) { - devicesByUniqueId = new ConcurrentHashMap<>(); - } - } finally { - writeUnlock(); - } dataRefreshDelay = config.getLong(Keys.DATABASE_REFRESH_DELAY) * 1000; refreshLastPositions(); } @@ -81,24 +64,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - @Override - public Device getByUniqueId(String uniqueId) { - boolean forceUpdate; - try { - readLock(); - forceUpdate = !devicesByUniqueId.containsKey(uniqueId) && !config.getBoolean(Keys.DATABASE_IGNORE_UNKNOWN); - } finally { - readUnlock(); - } - updateDeviceCache(forceUpdate); - try { - readLock(); - return devicesByUniqueId.get(uniqueId); - } finally { - readUnlock(); - } - } - @Override public Set getAllItems() { Set result = super.getAllItems(); @@ -132,35 +97,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - private void addByUniqueId(Device device) { - try { - writeLock(); - if (devicesByUniqueId == null) { - devicesByUniqueId = new ConcurrentHashMap<>(); - } - devicesByUniqueId.put(device.getUniqueId(), device); - } finally { - writeUnlock(); - } - } - - private void removeByUniqueId(String deviceUniqueId) { - try { - writeLock(); - if (devicesByUniqueId != null) { - devicesByUniqueId.remove(deviceUniqueId); - } - } finally { - writeUnlock(); - } - } - - @Override - protected void addNewItem(Device device) { - super.addNewItem(device); - addByUniqueId(device); - } - @Override protected void updateCachedItem(Device device) { Device cachedDevice = getById(device.getId()); @@ -172,20 +108,14 @@ public class DeviceManager extends BaseObjectManager implements Identity cachedDevice.setModel(device.getModel()); cachedDevice.setDisabled(device.getDisabled()); cachedDevice.setAttributes(device.getAttributes()); - if (!device.getUniqueId().equals(cachedDevice.getUniqueId())) { - removeByUniqueId(cachedDevice.getUniqueId()); - cachedDevice.setUniqueId(device.getUniqueId()); - addByUniqueId(cachedDevice); - } + cachedDevice.setUniqueId(device.getUniqueId()); } @Override protected void removeCachedItem(long deviceId) { Device cachedDevice = getById(deviceId); if (cachedDevice != null) { - String deviceUniqueId = cachedDevice.getUniqueId(); super.removeCachedItem(deviceId); - removeByUniqueId(deviceUniqueId); } positions.remove(deviceId); } diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index 5ef1c8c5e..b42d4c292 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -22,8 +22,6 @@ public interface IdentityManager { Device getById(long id); - Device getByUniqueId(String uniqueId) throws Exception; - Position getLastPosition(long deviceId); boolean isLatestPosition(Position position); diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java index 225089d5c..58b922d95 100644 --- a/src/main/java/org/traccar/helper/model/AttributeUtil.java +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -15,11 +15,9 @@ */ package org.traccar.helper.model; -import org.traccar.Context; import org.traccar.config.ConfigKey; import org.traccar.config.KeyType; import org.traccar.config.Keys; -import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.session.cache.CacheManager; diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 54035553f..6db568300 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -31,7 +31,6 @@ public class BaseTest { when(device.getId()).thenReturn(1L); var identityManager = mock(IdentityManager.class); when(identityManager.getById(anyLong())).thenReturn(device); - when(identityManager.getByUniqueId(any())).thenReturn(device); decoder.setIdentityManager(identityManager); var cacheManager = mock(CacheManager.class); when(cacheManager.getConfig()).thenReturn(config); @@ -72,7 +71,6 @@ public class BaseTest { encoder.setCacheManager(cacheManager); var identityManager = mock(IdentityManager.class); when(identityManager.getById(anyLong())).thenReturn(device); - when(identityManager.getByUniqueId(any())).thenReturn(device); encoder.setIdentityManager(identityManager); return encoder; } -- cgit v1.2.3 From ddbe4d7de6ae7590e2b927066312597efa129393 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 11:08:32 -0700 Subject: Remove positions from manager --- src/main/java/org/traccar/BaseProtocolDecoder.java | 2 +- src/main/java/org/traccar/Context.java | 4 +- src/main/java/org/traccar/MainEventHandler.java | 28 ++++++- src/main/java/org/traccar/MainModule.java | 4 +- src/main/java/org/traccar/api/AsyncSocket.java | 14 +++- .../java/org/traccar/api/AsyncSocketServlet.java | 7 +- .../org/traccar/api/resource/PositionResource.java | 14 +--- .../java/org/traccar/database/DataManager.java | 24 +----- .../java/org/traccar/database/DeviceManager.java | 93 +--------------------- .../java/org/traccar/database/IdentityManager.java | 5 -- .../java/org/traccar/handler/DistanceHandler.java | 10 +-- .../org/traccar/handler/EngineHoursHandler.java | 10 +-- .../java/org/traccar/handler/GeocoderHandler.java | 11 ++- .../traccar/handler/events/AlertEventHandler.java | 10 +-- .../handler/events/BehaviorEventHandler.java | 10 +-- .../traccar/handler/events/DriverEventHandler.java | 18 ++--- .../handler/events/IgnitionEventHandler.java | 15 ++-- .../handler/events/MaintenanceEventHandler.java | 3 +- .../traccar/handler/events/MotionEventHandler.java | 12 +-- .../org/traccar/helper/model/PositionUtil.java | 17 ++++ .../org/traccar/reports/common/ReportUtils.java | 2 +- .../org/traccar/handler/DistanceHandlerTest.java | 4 +- .../handler/events/AlertEventHandlerTest.java | 4 +- .../handler/events/IgnitionEventHandlerTest.java | 4 +- 24 files changed, 122 insertions(+), 203 deletions(-) diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index 076b52e96..f7e726f02 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -156,7 +156,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { if (position.getDeviceId() != 0) { position.setOutdated(true); - Position last = identityManager.getLastPosition(position.getDeviceId()); + Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { position.setFixTime(last.getFixTime()); position.setValid(last.getValid()); diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 854af97c0..c549b20c2 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -24,7 +24,6 @@ import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.session.ConnectionManager; import org.traccar.storage.Storage; public final class Context { @@ -69,8 +68,7 @@ public final class Context { deviceManager = new DeviceManager( config, - Main.getInjector().getInstance(DataManager.class), - Main.getInjector().getInstance(ConnectionManager.class)); + Main.getInjector().getInstance(DataManager.class)); identityManager = deviceManager; diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 7fff2e13f..e1aee3cc8 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -28,10 +28,16 @@ import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.helper.NetworkUtil; +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.Arrays; @@ -46,10 +52,15 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Set connectionlessProtocols = new HashSet<>(); private final Set logAttributes = new LinkedHashSet<>(); + private final CacheManager cacheManager; + private final Storage storage; private final ConnectionManager connectionManager; @Inject - public MainEventHandler(Config config, ConnectionManager connectionManager) { + public MainEventHandler( + Config config, CacheManager cacheManager, Storage storage, ConnectionManager connectionManager) { + this.cacheManager = cacheManager; + this.storage = storage; this.connectionManager = connectionManager; String connectionlessProtocolList = config.getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { @@ -64,8 +75,19 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { Position position = (Position) msg; try { - Context.getDeviceManager().updateLatestPosition(position); - Main.getInjector().getInstance(CacheManager.class).updatePosition(position); + if (PositionUtil.isLatest(cacheManager, position)) { + Device device = new Device(); + device.setId(position.getDeviceId()); + device.setPositionId(position.getId()); + storage.updateObject(device, new Request( + new Columns.Include("positionId"), + new Condition.Equals("id", "id"))); + + cacheManager.updatePosition(position); + cacheManager.getObject(Device.class, position.getDeviceId()).setPositionId(position.getId()); + + connectionManager.updatePosition(position); + } } catch (StorageException error) { LOGGER.warn("Failed to update device", error); } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a9337a3a2..a7e531808 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -252,9 +252,9 @@ public class MainModule extends AbstractModule { @Provides public static GeocoderHandler provideGeocoderHandler( - Config config, @Nullable Geocoder geocoder, IdentityManager identityManager) { + Config config, @Nullable Geocoder geocoder, CacheManager cacheManager) { if (geocoder != null) { - return new GeocoderHandler(config, geocoder, identityManager); + return new GeocoderHandler(config, geocoder, cacheManager); } return null; } diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java index 3239d36c4..40aa68e88 100644 --- a/src/main/java/org/traccar/api/AsyncSocket.java +++ b/src/main/java/org/traccar/api/AsyncSocket.java @@ -21,11 +21,13 @@ import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.helper.model.PositionUtil; import org.traccar.session.ConnectionManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; import java.util.Collection; import java.util.Collections; @@ -42,11 +44,13 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U private final ObjectMapper objectMapper; private final ConnectionManager connectionManager; + private final Storage storage; private final long userId; - public AsyncSocket(ObjectMapper objectMapper, ConnectionManager connectionManager, long userId) { + public AsyncSocket(ObjectMapper objectMapper, ConnectionManager connectionManager, Storage storage, long userId) { this.objectMapper = objectMapper; this.connectionManager = connectionManager; + this.storage = storage; this.userId = userId; } @@ -55,7 +59,11 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U super.onWebSocketConnect(session); Map> data = new HashMap<>(); - data.put(KEY_POSITIONS, Context.getDeviceManager().getInitialState(userId)); + try { + data.put(KEY_POSITIONS, PositionUtil.getLatestPositions(storage, userId)); + } catch (StorageException e) { + throw new RuntimeException(e); + } sendData(data); connectionManager.addListener(userId, this); diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 7c532179b..7d9fdf0ed 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -22,6 +22,7 @@ import org.traccar.Context; import org.traccar.api.resource.SessionResource; import org.traccar.config.Keys; import org.traccar.session.ConnectionManager; +import org.traccar.storage.Storage; import javax.inject.Inject; import javax.inject.Singleton; @@ -33,11 +34,13 @@ public class AsyncSocketServlet extends JettyWebSocketServlet { private final ObjectMapper objectMapper; private final ConnectionManager connectionManager; + private final Storage storage; @Inject - public AsyncSocketServlet(ObjectMapper objectMapper, ConnectionManager connectionManager) { + public AsyncSocketServlet(ObjectMapper objectMapper, ConnectionManager connectionManager, Storage storage) { this.objectMapper = objectMapper; this.connectionManager = connectionManager; + this.storage = storage; } @Override @@ -46,7 +49,7 @@ public class AsyncSocketServlet extends JettyWebSocketServlet { factory.setCreator((req, resp) -> { if (req.getSession() != null) { long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); - return new AsyncSocket(objectMapper, connectionManager, userId); + return new AsyncSocket(objectMapper, connectionManager, storage, userId); } else { return null; } diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 099d97632..cac64feb1 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -17,10 +17,8 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; import org.traccar.helper.model.PositionUtil; -import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Position; -import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -37,7 +35,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; -import java.util.stream.Collectors; @Path("positions") @Produces(MediaType.APPLICATION_JSON) @@ -68,16 +65,7 @@ public class PositionResource extends BaseResource { new Columns.All(), new Condition.LatestPositions(deviceId))); } } else { - var devices = storage.getObjects(Device.class, new Request( - new Columns.Include("id"), - new Condition.Permission(User.class, getUserId(), Device.class))); - var deviceIds = devices.stream().map(BaseModel::getId).collect(Collectors.toUnmodifiableSet()); - - var positions = storage.getObjects(Position.class, new Request( - new Columns.All(), new Condition.LatestPositions())); - return positions.stream() - .filter(position -> deviceIds.contains(position.getDeviceId())) - .collect(Collectors.toList()); + return PositionUtil.getLatestPositions(storage, getUserId()); } } diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index aa600e375..f80f429e1 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -24,20 +24,17 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Limit; -import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.Collection; -import java.util.Date; public class DataManager { private final Storage storage; @Inject - public DataManager(Storage storage) throws Exception { + public DataManager(Storage storage) { this.storage = storage; } @@ -47,25 +44,6 @@ public class DataManager { new Condition.Equals("id", "id"))); } - public Position getPrecedingPosition(long deviceId, Date date) throws StorageException { - return storage.getObject(Position.class, new Request( - new Columns.All(), - new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), - new Condition.Compare("fixTime", "<=", "time", date)), - new Order(true, "fixTime"), - new Limit(1))); - } - - public void updateLatestPosition(Position position) throws StorageException { - Device device = new Device(); - device.setId(position.getDeviceId()); - device.setPositionId(position.getId()); - storage.updateObject(device, new Request( - new Columns.Include("positionId"), - new Condition.Equals("id", "id"))); - } - public Collection getLatestPositions() throws StorageException { return storage.getObjects(Position.class, new Request( new Columns.All(), diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 841915f1c..4516255c1 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -15,21 +15,13 @@ */ package org.traccar.database; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Device; -import org.traccar.model.Position; -import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceState; import org.traccar.storage.StorageException; import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -37,23 +29,15 @@ import java.util.concurrent.atomic.AtomicLong; public class DeviceManager extends BaseObjectManager implements IdentityManager { - private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); - - private final ConnectionManager connectionManager; private final long dataRefreshDelay; private final AtomicLong devicesLastUpdate = new AtomicLong(); - private final Map positions = new ConcurrentHashMap<>(); - private final Map deviceStates = new ConcurrentHashMap<>(); - public DeviceManager( - Config config, DataManager dataManager, ConnectionManager connectionManager) { + public DeviceManager(Config config, DataManager dataManager) { super(dataManager, Device.class); - this.connectionManager = connectionManager; dataRefreshDelay = config.getLong(Keys.DATABASE_REFRESH_DELAY) * 1000; - refreshLastPositions(); } public void updateDeviceCache(boolean force) { @@ -78,25 +62,6 @@ public class DeviceManager extends BaseObjectManager implements Identity return getItems(getAllItems()); } - public Set getAllUserItems(long userId) { - return Context.getPermissionsManager().getDevicePermissions(userId); - } - - public Set getUserItems(long userId) { - if (Context.getPermissionsManager() != null) { - Set result = new HashSet<>(); - for (long deviceId : Context.getPermissionsManager().getDevicePermissions(userId)) { - Device device = getById(deviceId); - if (device != null && !device.getDisabled()) { - result.add(deviceId); - } - } - return result; - } else { - return new HashSet<>(); - } - } - @Override protected void updateCachedItem(Device device) { Device cachedDevice = getById(device.getId()); @@ -117,7 +82,6 @@ public class DeviceManager extends BaseObjectManager implements Identity if (cachedDevice != null) { super.removeCachedItem(deviceId); } - positions.remove(deviceId); } public void updateDeviceStatus(Device device) throws StorageException { @@ -128,61 +92,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - private void refreshLastPositions() { - if (getDataManager() != null) { - try { - for (Position position : getDataManager().getLatestPositions()) { - positions.put(position.getDeviceId(), position); - } - } catch (StorageException error) { - LOGGER.warn("Load latest positions error", error); - } - } - } - - public boolean isLatestPosition(Position position) { - Position lastPosition = getLastPosition(position.getDeviceId()); - return lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) >= 0; - } - - public void updateLatestPosition(Position position) throws StorageException { - - if (isLatestPosition(position)) { - - getDataManager().updateLatestPosition(position); - - Device device = getById(position.getDeviceId()); - if (device != null) { - device.setPositionId(position.getId()); - } - - positions.put(position.getDeviceId(), position); - - connectionManager.updatePosition(position); - } - } - - @Override - public Position getLastPosition(long deviceId) { - return positions.get(deviceId); - } - - public Collection getInitialState(long userId) { - - List result = new LinkedList<>(); - - if (Context.getPermissionsManager() != null) { - for (long deviceId : Context.getPermissionsManager().getUserAdmin(userId) - ? getAllUserItems(userId) : getUserItems(userId)) { - if (positions.containsKey(deviceId)) { - result.add(positions.get(deviceId)); - } - } - } - - return result; - } - public DeviceState getDeviceState(long deviceId) { DeviceState deviceState = deviceStates.get(deviceId); if (deviceState == null) { diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java index b42d4c292..1e0eb00c5 100644 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ b/src/main/java/org/traccar/database/IdentityManager.java @@ -16,14 +16,9 @@ package org.traccar.database; import org.traccar.model.Device; -import org.traccar.model.Position; public interface IdentityManager { Device getById(long id); - Position getLastPosition(long deviceId); - - boolean isLatestPosition(Position position); - } diff --git a/src/main/java/org/traccar/handler/DistanceHandler.java b/src/main/java/org/traccar/handler/DistanceHandler.java index 08c8c068d..fb82b5d8e 100644 --- a/src/main/java/org/traccar/handler/DistanceHandler.java +++ b/src/main/java/org/traccar/handler/DistanceHandler.java @@ -20,9 +20,9 @@ import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.helper.DistanceCalculator; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import java.math.BigDecimal; @@ -31,15 +31,15 @@ import java.math.RoundingMode; @ChannelHandler.Sharable public class DistanceHandler extends BaseDataHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; private final boolean filter; private final int coordinatesMinError; private final int coordinatesMaxError; @Inject - public DistanceHandler(Config config, IdentityManager identityManager) { - this.identityManager = identityManager; + public DistanceHandler(Config config, CacheManager cacheManager) { + this.cacheManager = cacheManager; this.filter = config.getBoolean(Keys.COORDINATES_FILTER); this.coordinatesMinError = config.getInteger(Keys.COORDINATES_MIN_ERROR); this.coordinatesMaxError = config.getInteger(Keys.COORDINATES_MAX_ERROR); @@ -54,7 +54,7 @@ public class DistanceHandler extends BaseDataHandler { } double totalDistance = 0.0; - Position last = identityManager != null ? identityManager.getLastPosition(position.getDeviceId()) : null; + Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { totalDistance = last.getDouble(Position.KEY_TOTAL_DISTANCE); if (!position.getAttributes().containsKey(Position.KEY_DISTANCE)) { diff --git a/src/main/java/org/traccar/handler/EngineHoursHandler.java b/src/main/java/org/traccar/handler/EngineHoursHandler.java index be2a46ade..bfffdcb0c 100644 --- a/src/main/java/org/traccar/handler/EngineHoursHandler.java +++ b/src/main/java/org/traccar/handler/EngineHoursHandler.java @@ -18,25 +18,25 @@ package org.traccar.handler; import io.netty.channel.ChannelHandler; import org.traccar.BaseDataHandler; -import org.traccar.database.IdentityManager; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @ChannelHandler.Sharable public class EngineHoursHandler extends BaseDataHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public EngineHoursHandler(IdentityManager identityManager) { - this.identityManager = identityManager; + public EngineHoursHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Position handlePosition(Position position) { if (!position.getAttributes().containsKey(Position.KEY_HOURS)) { - Position last = identityManager.getLastPosition(position.getDeviceId()); + Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { long hours = last.getLong(Position.KEY_HOURS); if (last.getBoolean(Position.KEY_IGNITION) && position.getBoolean(Position.KEY_IGNITION)) { diff --git a/src/main/java/org/traccar/handler/GeocoderHandler.java b/src/main/java/org/traccar/handler/GeocoderHandler.java index 075bdf815..0248fca05 100644 --- a/src/main/java/org/traccar/handler/GeocoderHandler.java +++ b/src/main/java/org/traccar/handler/GeocoderHandler.java @@ -22,9 +22,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.geocoder.Geocoder; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; @ChannelHandler.Sharable public class GeocoderHandler extends ChannelInboundHandlerAdapter { @@ -32,15 +32,14 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(GeocoderHandler.class); private final Geocoder geocoder; - private final IdentityManager identityManager; + private final CacheManager cacheManager; private final boolean ignorePositions; private final boolean processInvalidPositions; private final int geocoderReuseDistance; - public GeocoderHandler( - Config config, Geocoder geocoder, IdentityManager identityManager) { + public GeocoderHandler(Config config, Geocoder geocoder, CacheManager cacheManager) { this.geocoder = geocoder; - this.identityManager = identityManager; + this.cacheManager = cacheManager; ignorePositions = config.getBoolean(Keys.GEOCODER_IGNORE_POSITIONS); processInvalidPositions = config.getBoolean(Keys.GEOCODER_PROCESS_INVALID_POSITIONS); geocoderReuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0); @@ -52,7 +51,7 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { final Position position = (Position) message; if (processInvalidPositions || position.getValid()) { if (geocoderReuseDistance != 0) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null && lastPosition.getAddress() != null && position.getDouble(Position.KEY_DISTANCE) <= geocoderReuseDistance) { position.setAddress(lastPosition.getAddress()); diff --git a/src/main/java/org/traccar/handler/events/AlertEventHandler.java b/src/main/java/org/traccar/handler/events/AlertEventHandler.java index 6e7b0b16e..75626ca6c 100644 --- a/src/main/java/org/traccar/handler/events/AlertEventHandler.java +++ b/src/main/java/org/traccar/handler/events/AlertEventHandler.java @@ -21,21 +21,21 @@ import java.util.Map; import io.netty.channel.ChannelHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @ChannelHandler.Sharable public class AlertEventHandler extends BaseEventHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; private final boolean ignoreDuplicateAlerts; @Inject - public AlertEventHandler(Config config, IdentityManager identityManager) { - this.identityManager = identityManager; + public AlertEventHandler(Config config, CacheManager cacheManager) { + this.cacheManager = cacheManager; ignoreDuplicateAlerts = config.getBoolean(Keys.EVENT_IGNORE_DUPLICATE_ALERTS); } @@ -45,7 +45,7 @@ public class AlertEventHandler extends BaseEventHandler { if (alarm != null) { boolean ignoreAlert = false; if (ignoreDuplicateAlerts) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null && alarm.equals(lastPosition.getAttributes().get(Position.KEY_ALARM))) { ignoreAlert = true; } diff --git a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java index bbf749cdc..3c2fa6a97 100644 --- a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java @@ -18,10 +18,10 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.helper.UnitsConverter; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import java.util.Collections; @@ -33,19 +33,19 @@ public class BehaviorEventHandler extends BaseEventHandler { private final double accelerationThreshold; private final double brakingThreshold; - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public BehaviorEventHandler(Config config, IdentityManager identityManager) { + public BehaviorEventHandler(Config config, CacheManager cacheManager) { accelerationThreshold = config.getDouble(Keys.EVENT_BEHAVIOR_ACCELERATION_THRESHOLD); brakingThreshold = config.getDouble(Keys.EVENT_BEHAVIOR_BRAKING_THRESHOLD); - this.identityManager = identityManager; + this.cacheManager = cacheManager; } @Override protected Map analyzePosition(Position position) { - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null && position.getFixTime().equals(lastPosition.getFixTime())) { double acceleration = UnitsConverter.mpsFromKnots(position.getSpeed() - lastPosition.getSpeed()) * 1000 / (position.getFixTime().getTime() - lastPosition.getFixTime().getTime()); diff --git a/src/main/java/org/traccar/handler/events/DriverEventHandler.java b/src/main/java/org/traccar/handler/events/DriverEventHandler.java index 510ac3465..1ad66ba64 100644 --- a/src/main/java/org/traccar/handler/events/DriverEventHandler.java +++ b/src/main/java/org/traccar/handler/events/DriverEventHandler.java @@ -16,35 +16,35 @@ */ package org.traccar.handler.events; -import java.util.Collections; -import java.util.Map; - import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import java.util.Collections; +import java.util.Map; @ChannelHandler.Sharable public class DriverEventHandler extends BaseEventHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public DriverEventHandler(IdentityManager identityManager) { - this.identityManager = identityManager; + public DriverEventHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Map analyzePosition(Position position) { - if (!identityManager.isLatestPosition(position)) { + if (!PositionUtil.isLatest(cacheManager, position)) { return null; } String driverUniqueId = position.getString(Position.KEY_DRIVER_UNIQUE_ID); if (driverUniqueId != null) { String oldDriverUniqueId = null; - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null) { oldDriverUniqueId = lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); } diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java index 9887c9db6..6e411539c 100644 --- a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java @@ -20,27 +20,28 @@ import java.util.Collections; import java.util.Map; import io.netty.channel.ChannelHandler; -import org.traccar.database.IdentityManager; +import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @ChannelHandler.Sharable public class IgnitionEventHandler extends BaseEventHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; @Inject - public IgnitionEventHandler(IdentityManager identityManager) { - this.identityManager = identityManager; + public IgnitionEventHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; } @Override protected Map analyzePosition(Position position) { - Device device = identityManager.getById(position.getDeviceId()); - if (device == null || !identityManager.isLatestPosition(position)) { + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); + if (device == null || !PositionUtil.isLatest(cacheManager, position)) { return null; } @@ -49,7 +50,7 @@ public class IgnitionEventHandler extends BaseEventHandler { if (position.getAttributes().containsKey(Position.KEY_IGNITION)) { boolean ignition = position.getBoolean(Position.KEY_IGNITION); - Position lastPosition = identityManager.getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_IGNITION)) { boolean oldIgnition = lastPosition.getBoolean(Position.KEY_IGNITION); diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index f85aab043..be3e9bf8d 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.Map; import io.netty.channel.ChannelHandler; -import org.traccar.Context; import org.traccar.model.Event; import org.traccar.model.Maintenance; import org.traccar.model.Position; @@ -40,7 +39,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { @Override protected Map analyzePosition(Position position) { - Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) < 0) { return null; } diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 2c381e530..724e9bf15 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -18,13 +18,13 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.common.TripsConfig; import org.traccar.session.DeviceState; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import java.util.Collections; @@ -33,13 +33,13 @@ import java.util.Map; @ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { - private final IdentityManager identityManager; + private final CacheManager cacheManager; private final DeviceManager deviceManager; private final TripsConfig tripsConfig; @Inject - public MotionEventHandler(IdentityManager identityManager, DeviceManager deviceManager, TripsConfig tripsConfig) { - this.identityManager = identityManager; + public MotionEventHandler(CacheManager cacheManager, DeviceManager deviceManager, TripsConfig tripsConfig) { + this.cacheManager = cacheManager; this.deviceManager = deviceManager; this.tripsConfig = tripsConfig; } @@ -113,11 +113,11 @@ public class MotionEventHandler extends BaseEventHandler { protected Map analyzePosition(Position position) { long deviceId = position.getDeviceId(); - Device device = identityManager.getById(deviceId); + Device device = cacheManager.getObject(Device.class, deviceId); if (device == null) { return null; } - if (!identityManager.isLatestPosition(position) + if (!PositionUtil.isLatest(cacheManager, position) || !tripsConfig.getProcessInvalidPositions() && !position.getValid()) { return null; } diff --git a/src/main/java/org/traccar/helper/model/PositionUtil.java b/src/main/java/org/traccar/helper/model/PositionUtil.java index 566e31bc5..31f828947 100644 --- a/src/main/java/org/traccar/helper/model/PositionUtil.java +++ b/src/main/java/org/traccar/helper/model/PositionUtil.java @@ -15,7 +15,10 @@ */ package org.traccar.helper.model; +import org.traccar.model.BaseModel; +import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.session.cache.CacheManager; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -26,6 +29,7 @@ import org.traccar.storage.query.Request; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; public final class PositionUtil { @@ -60,4 +64,17 @@ public final class PositionUtil { new Order("fixTime"))); } + public static List getLatestPositions(Storage storage, long userId) throws StorageException { + var devices = storage.getObjects(Device.class, new Request( + new Columns.Include("id"), + new Condition.Permission(User.class, userId, Device.class))); + var deviceIds = devices.stream().map(BaseModel::getId).collect(Collectors.toUnmodifiableSet()); + + var positions = storage.getObjects(Position.class, new Request( + new Columns.All(), new Condition.LatestPositions())); + return positions.stream() + .filter(position -> deviceIds.contains(position.getDeviceId())) + .collect(Collectors.toList()); + } + } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 84866a67b..bb37bfa9c 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -346,7 +346,7 @@ public class ReportUtils { ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); - MotionEventHandler motionHandler = new MotionEventHandler(identityManager, deviceManager, tripsConfig); + MotionEventHandler motionHandler = new MotionEventHandler(null, deviceManager, tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; diff --git a/src/test/java/org/traccar/handler/DistanceHandlerTest.java b/src/test/java/org/traccar/handler/DistanceHandlerTest.java index f7c6e42cd..a18b14edd 100644 --- a/src/test/java/org/traccar/handler/DistanceHandlerTest.java +++ b/src/test/java/org/traccar/handler/DistanceHandlerTest.java @@ -3,15 +3,17 @@ package org.traccar.handler; import org.junit.Test; import org.traccar.config.Config; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; public class DistanceHandlerTest { @Test public void testCalculateDistance() { - DistanceHandler distanceHandler = new DistanceHandler(new Config(), null); + DistanceHandler distanceHandler = new DistanceHandler(new Config(), mock(CacheManager.class)); Position position = distanceHandler.handlePosition(new Position()); diff --git a/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java b/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java index d6cf32ca3..550a93da3 100644 --- a/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/AlertEventHandlerTest.java @@ -3,9 +3,9 @@ package org.traccar.handler.events; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.config.Config; -import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import java.util.Map; @@ -18,7 +18,7 @@ public class AlertEventHandlerTest extends BaseTest { @Test public void testAlertEventHandler() { - AlertEventHandler alertEventHandler = new AlertEventHandler(new Config(), mock(IdentityManager.class)); + AlertEventHandler alertEventHandler = new AlertEventHandler(new Config(), mock(CacheManager.class)); Position position = new Position(); position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); diff --git a/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java index 0de80dd70..84898bea0 100644 --- a/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/IgnitionEventHandlerTest.java @@ -2,9 +2,9 @@ package org.traccar.handler.events; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.database.IdentityManager; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import java.util.Map; @@ -16,7 +16,7 @@ public class IgnitionEventHandlerTest extends BaseTest { @Test public void testIgnitionEventHandler() { - IgnitionEventHandler ignitionEventHandler = new IgnitionEventHandler(mock(IdentityManager.class)); + IgnitionEventHandler ignitionEventHandler = new IgnitionEventHandler(mock(CacheManager.class)); Position position = new Position(); position.set(Position.KEY_IGNITION, true); -- cgit v1.2.3 From 03b50c61afd7c9d7e19a76feb261147dd0f69588 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 11:44:40 -0700 Subject: Remove identity manager --- src/main/java/org/traccar/BaseProtocolDecoder.java | 11 ------ src/main/java/org/traccar/BaseProtocolEncoder.java | 15 +------- src/main/java/org/traccar/Context.java | 9 ----- src/main/java/org/traccar/MainEventHandler.java | 14 +++---- src/main/java/org/traccar/MainModule.java | 6 --- src/main/java/org/traccar/WebDataHandler.java | 10 ++--- .../traccar/api/resource/AttributeResource.java | 4 +- .../java/org/traccar/database/DeviceManager.java | 2 +- .../java/org/traccar/database/IdentityManager.java | 24 ------------ .../traccar/handler/ComputedAttributesHandler.java | 8 +--- .../traccar/protocol/CastelProtocolEncoder.java | 4 +- .../traccar/protocol/GalileoProtocolDecoder.java | 3 +- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 7 +--- .../traccar/protocol/MeiligaoProtocolDecoder.java | 3 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 3 +- .../traccar/protocol/PretraceProtocolEncoder.java | 2 +- .../org/traccar/protocol/Pt502ProtocolDecoder.java | 3 +- .../traccar/protocol/TeltonikaProtocolDecoder.java | 8 ++-- .../org/traccar/reports/EventsReportProvider.java | 3 +- .../org/traccar/reports/RouteReportProvider.java | 3 +- .../org/traccar/reports/StopsReportProvider.java | 3 +- .../org/traccar/reports/SummaryReportProvider.java | 6 +-- .../org/traccar/reports/TripsReportProvider.java | 3 +- .../org/traccar/reports/common/ReportUtils.java | 18 +++++---- src/test/java/org/traccar/BaseTest.java | 9 ----- src/test/java/org/traccar/WebDataHandlerTest.java | 8 ++-- .../traccar/handler/ComputedAttributesTest.java | 2 +- .../java/org/traccar/reports/ReportUtilsTest.java | 43 +++++++++++----------- 28 files changed, 75 insertions(+), 159 deletions(-) delete mode 100644 src/main/java/org/traccar/database/IdentityManager.java diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index f7e726f02..382daf92f 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -19,7 +19,6 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.config.Keys; import org.traccar.database.CommandsManager; -import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.helper.UnitsConverter; @@ -47,7 +46,6 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private final Protocol protocol; - private IdentityManager identityManager; private CacheManager cacheManager; private ConnectionManager connectionManager; private StatisticsManager statisticsManager; @@ -58,15 +56,6 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { this.protocol = protocol; } - public IdentityManager getIdentityManager() { - return identityManager; - } - - @Inject - public void setIdentityManager(IdentityManager identityManager) { - this.identityManager = identityManager; - } - public CacheManager getCacheManager() { return cacheManager; } diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index 612d91c57..bc1180a08 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -21,10 +21,10 @@ import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.database.IdentityManager; import org.traccar.helper.NetworkUtil; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; +import org.traccar.model.Device; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; @@ -39,8 +39,6 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter private CacheManager cacheManager; - private IdentityManager identityManager; - public BaseProtocolEncoder(Protocol protocol) { this.protocol = protocol; } @@ -54,21 +52,12 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter this.cacheManager = cacheManager; } - public IdentityManager getIdentityManager() { - return identityManager; - } - - @Inject - public void setIdentityManager(IdentityManager identityManager) { - this.identityManager = identityManager; - } - public String getProtocolName() { return protocol != null ? protocol.getName() : PROTOCOL_UNKNOWN; } protected String getUniqueId(long deviceId) { - return identityManager.getById(deviceId).getUniqueId(); + return cacheManager.getObject(Device.class, deviceId).getUniqueId(); } protected void initDevicePassword(Command command, String defaultPassword) { diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index c549b20c2..45d075912 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -19,7 +19,6 @@ import org.traccar.config.Config; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; @@ -37,12 +36,6 @@ public final class Context { return config; } - private static IdentityManager identityManager; - - public static IdentityManager getIdentityManager() { - return identityManager; - } - private static DeviceManager deviceManager; public static DeviceManager getDeviceManager() { @@ -70,8 +63,6 @@ public final class Context { config, Main.getInjector().getInstance(DataManager.class)); - identityManager = deviceManager; - permissionsManager = new PermissionsManager( Main.getInjector().getInstance(DataManager.class), Main.getInjector().getInstance(Storage.class)); diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index e1aee3cc8..d2665cbcc 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -74,12 +74,14 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { if (msg instanceof Position) { Position position = (Position) msg; + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); + try { if (PositionUtil.isLatest(cacheManager, position)) { - Device device = new Device(); - device.setId(position.getDeviceId()); - device.setPositionId(position.getId()); - storage.updateObject(device, new Request( + Device updatedDevice = new Device(); + updatedDevice.setId(position.getDeviceId()); + updatedDevice.setPositionId(position.getId()); + storage.updateObject(updatedDevice, new Request( new Columns.Include("positionId"), new Condition.Equals("id", "id"))); @@ -92,11 +94,9 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { LOGGER.warn("Failed to update device", error); } - String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); - StringBuilder builder = new StringBuilder(); builder.append("[").append(NetworkUtil.session(ctx.channel())).append("] "); - builder.append("id: ").append(uniqueId); + builder.append("id: ").append(device.getUniqueId()); for (String attribute : logAttributes) { switch (attribute) { case "time": diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a7e531808..d57ee5d38 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -31,7 +31,6 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; @@ -108,11 +107,6 @@ public class MainModule extends AbstractModule { return Context.getConfig(); } - @Provides - public static IdentityManager provideIdentityManager() { - return Context.getIdentityManager(); - } - @Provides public static Client provideClient() { return ClientBuilder.newClient().register( diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index db99ecaf8..192a15bcf 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -26,7 +26,6 @@ import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.helper.Checksum; import org.traccar.model.Device; import org.traccar.model.Position; @@ -62,7 +61,6 @@ public class WebDataHandler extends BaseDataHandler { private static final String KEY_DEVICE = "device"; private final CacheManager cacheManager; - private final IdentityManager identityManager; private final ObjectMapper objectMapper; private final Client client; @@ -80,11 +78,9 @@ public class WebDataHandler extends BaseDataHandler { @Inject public WebDataHandler( - Config config, CacheManager cacheManager, IdentityManager identityManager, - ObjectMapper objectMapper, Client client) { + Config config, CacheManager cacheManager, ObjectMapper objectMapper, Client client) { this.cacheManager = cacheManager; - this.identityManager = identityManager; this.objectMapper = objectMapper; this.client = client; this.url = config.getString(Keys.FORWARD_URL); @@ -138,7 +134,7 @@ public class WebDataHandler extends BaseDataHandler { public String formatRequest(Position position) throws UnsupportedEncodingException, JsonProcessingException { - Device device = identityManager.getById(position.getDeviceId()); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); String request = url .replace("{name}", URLEncoder.encode(device.getName(), StandardCharsets.UTF_8.name())) @@ -302,7 +298,7 @@ public class WebDataHandler extends BaseDataHandler { private Map prepareJsonPayload(Position position) { Map data = new HashMap<>(); - Device device = identityManager.getById(position.getDeviceId()); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); data.put(KEY_POSITION, position); diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index 43d8a7ccd..fb74b9bbe 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -28,7 +28,6 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.traccar.Context; import org.traccar.api.ExtendedObjectResource; import org.traccar.config.Config; import org.traccar.model.Attribute; @@ -62,8 +61,7 @@ public class AttributeResource extends ExtendedObjectResource { new Columns.All(), new Condition.LatestPositions(deviceId))); - Object result = new ComputedAttributesHandler(config, Context.getIdentityManager(), null) - .computeAttribute(entity, position); + Object result = new ComputedAttributesHandler(config, null).computeAttribute(entity, position); if (result != null) { switch (entity.getType()) { case "number": diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 4516255c1..d6c442f10 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -27,7 +27,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -public class DeviceManager extends BaseObjectManager implements IdentityManager { +public class DeviceManager extends BaseObjectManager { private final long dataRefreshDelay; diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java deleted file mode 100644 index 1e0eb00c5..000000000 --- a/src/main/java/org/traccar/database/IdentityManager.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2015 - 2022 Anton Tananaev (anton@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.database; - -import org.traccar.model.Device; - -public interface IdentityManager { - - Device getById(long id); - -} diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index bec3d38e0..82ac4e804 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; @@ -47,7 +46,6 @@ public class ComputedAttributesHandler extends BaseDataHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ComputedAttributesHandler.class); - private final IdentityManager identityManager; private final CacheManager cacheManager; private final JexlEngine engine; @@ -55,9 +53,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private final boolean includeDeviceAttributes; @Inject - public ComputedAttributesHandler( - Config config, IdentityManager identityManager, CacheManager cacheManager) { - this.identityManager = identityManager; + public ComputedAttributesHandler(Config config, CacheManager cacheManager) { this.cacheManager = cacheManager; engine = new JexlEngine(); engine.setStrict(true); @@ -68,7 +64,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private MapContext prepareContext(Position position) { MapContext result = new MapContext(); if (includeDeviceAttributes) { - Device device = identityManager.getById(position.getDeviceId()); + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); if (device != null) { for (Object key : device.getAttributes().keySet()) { result.set((String) key, device.getAttributes().get(key)); diff --git a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java index 0fb4bf8b4..61dde3e80 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@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 CastelProtocolEncoder extends BaseProtocolEncoder { private ByteBuf encodeContent(long deviceId, short type, ByteBuf content) { ByteBuf buf = Unpooled.buffer(0); - String uniqueId = getIdentityManager().getById(deviceId).getUniqueId(); + String uniqueId = getUniqueId(deviceId); buf.writeByte('@'); buf.writeByte('@'); diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index a2ba7b029..bf14d47e0 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -320,14 +320,13 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 4b9757874..c53fbfe5a 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -31,7 +31,6 @@ import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; -import org.traccar.model.Device; import org.traccar.model.Network; import org.traccar.model.Position; import org.traccar.model.WifiAccessPoint; @@ -1026,8 +1025,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (photo.writableBytes() > 0) { sendPhotoRequest(channel, pictureId); } else { - Device device = getIdentityManager().getById(deviceSession.getDeviceId()); - position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photos.remove(pictureId).release(); } @@ -1262,8 +1260,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, new Date(timestamp)); - Device device = getIdentityManager().getById(deviceSession.getDeviceId()); - position.set(Position.KEY_IMAGE, writeMediaFile(device.getUniqueId(), photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photos.remove(mediaId).release(); } } diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index 0b6bf8663..f3b56973a 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -468,10 +468,9 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } else if (command == MSG_POSITION_IMAGE) { byte imageIndex = buf.readByte(); buf.readUnsignedByte(); // image upload type - String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); ByteBuf photo = photos.remove(imageIndex); try { - position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); } finally { photo.release(); } diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 30689436d..87459d3fc 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -19,6 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.model.Device; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -203,7 +204,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); } - String deviceModel = getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); + String deviceModel = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); if (deviceModel == null) { deviceModel = ""; } diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java index 106ba9537..a109e7a07 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java @@ -34,7 +34,7 @@ public class PretraceProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - String uniqueId = getIdentityManager().getById(command.getDeviceId()).getUniqueId(); + String uniqueId = getUniqueId(command.getDeviceId()); switch (command.getType()) { case Command.TYPE_CUSTOM: diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java index 21b91203f..2a6a81a65 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -174,14 +174,13 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String uniqueId = getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); photo.release(); photo = null; diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index f91eef837..77047fe26 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -119,7 +119,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { return printable; } - private void decodeSerial(Channel channel, SocketAddress remoteAddress, Position position, ByteBuf buf) { + private void decodeSerial( + Channel channel, SocketAddress remoteAddress, DeviceSession deviceSession, Position position, ByteBuf buf) { getLastLocation(position, null); @@ -148,10 +149,9 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { channel, remoteAddress, photoId, photo.writerIndex(), Math.min(IMAGE_PACKET_MAX, photo.writableBytes())); } else { - String uniqueId = getIdentityManager().getById(position.getDeviceId()).getUniqueId(); photos.remove(photoId); try { - position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); + position.set(Position.KEY_IMAGE, writeMediaFile(deviceSession.getUniqueId(), photo, "jpg")); } finally { photo.release(); } @@ -601,7 +601,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { ByteBufUtil.hexDump(buf.readSlice(length))); } } else if (codec == CODEC_12) { - decodeSerial(channel, remoteAddress, position, buf); + decodeSerial(channel, remoteAddress, deviceSession, position, buf); } else { decodeLocation(position, buf, codec); } diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 4db842fdb..69d95d1be 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -17,7 +17,6 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Device; @@ -133,7 +132,7 @@ public class EventsReportProvider { } } DeviceReportSection deviceEvents = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); + Device device = reportUtils.getDevice(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index b4401bc87..2364cc0f3 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -17,7 +17,6 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; @@ -79,7 +78,7 @@ public class RouteReportProvider { for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { var positions = PositionUtil.getPositions(storage, deviceId, from, to); DeviceReportSection deviceRoutes = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); + Device device = reportUtils.getDevice(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 192d7a0f7..3b1f3c1fe 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -17,7 +17,6 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; @@ -86,7 +85,7 @@ public class StopsReportProvider { for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Collection stops = detectStops(deviceId, from, to); DeviceReportSection deviceStops = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); + Device device = reportUtils.getDevice(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index f3a9786b9..1f136adeb 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -17,7 +17,6 @@ package org.traccar.reports; import org.jxls.util.JxlsHelper; -import org.traccar.Context; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -58,10 +57,11 @@ public class SummaryReportProvider { this.storage = storage; } - private SummaryReportItem calculateSummaryResult(long deviceId, Collection positions) { + private SummaryReportItem calculateSummaryResult( + long deviceId, Collection positions) throws StorageException { SummaryReportItem result = new SummaryReportItem(); result.setDeviceId(deviceId); - result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); + result.setDeviceName(reportUtils.getDevice(deviceId).getName()); if (positions != null && !positions.isEmpty()) { Position firstPosition = null; Position previousPosition = null; diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 928609b9e..95612ab30 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -17,7 +17,6 @@ package org.traccar.reports; import org.apache.poi.ss.util.WorkbookUtil; -import org.traccar.Context; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.model.PositionUtil; @@ -85,7 +84,7 @@ public class TripsReportProvider { for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { Collection trips = detectTrips(deviceId, from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); - Device device = Context.getIdentityManager().getById(deviceId); + Device device = reportUtils.getDevice(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index bb37bfa9c..ab009161f 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -31,7 +31,6 @@ import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.geocoder.Geocoder; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; @@ -74,7 +73,6 @@ public class ReportUtils { private final Config config; private final Storage storage; private final PermissionsService permissionsService; - private final IdentityManager identityManager; private final DeviceManager deviceManager; private final TripsConfig tripsConfig; private final VelocityEngine velocityEngine; @@ -82,13 +80,12 @@ public class ReportUtils { @Inject public ReportUtils( - Config config, Storage storage, PermissionsService permissionsService, IdentityManager identityManager, + Config config, Storage storage, PermissionsService permissionsService, DeviceManager deviceManager, TripsConfig tripsConfig, VelocityEngine velocityEngine, @Nullable Geocoder geocoder) { this.config = config; this.storage = storage; this.permissionsService = permissionsService; - this.identityManager = identityManager; this.deviceManager = deviceManager; this.tripsConfig = tripsConfig; this.velocityEngine = velocityEngine; @@ -104,6 +101,12 @@ public class ReportUtils { new Condition.Permission(User.class, userId, clazz)))); } + public Device getDevice(long deviceId) throws StorageException { + return storage.getObject(Device.class, new Request( + new Columns.Include("id"), + new Condition.Equals("id", "id", deviceId))); + } + public void checkPeriodLimit(Date from, Date to) { long limit = config.getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; if (limit > 0 && to.getTime() - from.getTime() > limit) { @@ -212,7 +215,7 @@ public class ReportUtils { long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); trip.setDeviceId(deviceId); - trip.setDeviceName(identityManager.getById(deviceId).getName()); + trip.setDeviceName(getDevice(deviceId).getName()); trip.setStartPositionId(startTrip.getId()); trip.setStartLat(startTrip.getLatitude()); @@ -259,7 +262,8 @@ public class ReportUtils { } private StopReportItem calculateStop( - ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { + ArrayList positions, int startIndex, int endIndex, + boolean ignoreOdometer) throws StorageException { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); @@ -268,7 +272,7 @@ public class ReportUtils { long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); - stop.setDeviceName(identityManager.getById(deviceId).getName()); + stop.setDeviceName(getDevice(deviceId).getName()); stop.setPositionId(startStop.getId()); stop.setLatitude(startStop.getLatitude()); diff --git a/src/test/java/org/traccar/BaseTest.java b/src/test/java/org/traccar/BaseTest.java index 6db568300..c784150dd 100644 --- a/src/test/java/org/traccar/BaseTest.java +++ b/src/test/java/org/traccar/BaseTest.java @@ -3,7 +3,6 @@ package org.traccar; import io.netty.channel.Channel; import org.traccar.config.Config; import org.traccar.database.CommandsManager; -import org.traccar.database.IdentityManager; import org.traccar.database.MediaManager; import org.traccar.database.StatisticsManager; import org.traccar.model.Device; @@ -14,8 +13,6 @@ import org.traccar.session.cache.CacheManager; import java.net.SocketAddress; import java.util.HashSet; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; @@ -29,9 +26,6 @@ public class BaseTest { decoder.setConfig(config); var device = mock(Device.class); when(device.getId()).thenReturn(1L); - var identityManager = mock(IdentityManager.class); - when(identityManager.getById(anyLong())).thenReturn(device); - decoder.setIdentityManager(identityManager); var cacheManager = mock(CacheManager.class); when(cacheManager.getConfig()).thenReturn(config); when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); @@ -69,9 +63,6 @@ public class BaseTest { when(cacheManager.getConfig()).thenReturn(mock(Config.class)); when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); encoder.setCacheManager(cacheManager); - var identityManager = mock(IdentityManager.class); - when(identityManager.getById(anyLong())).thenReturn(device); - encoder.setIdentityManager(identityManager); return encoder; } diff --git a/src/test/java/org/traccar/WebDataHandlerTest.java b/src/test/java/org/traccar/WebDataHandlerTest.java index ff9c80ce6..1e6e1214f 100644 --- a/src/test/java/org/traccar/WebDataHandlerTest.java +++ b/src/test/java/org/traccar/WebDataHandlerTest.java @@ -3,13 +3,13 @@ package org.traccar; import org.junit.Test; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -28,10 +28,10 @@ public class WebDataHandlerTest extends ProtocolTest { when(device.getName()).thenReturn("test"); when(device.getUniqueId()).thenReturn("123456789012345"); when(device.getStatus()).thenReturn(Device.STATUS_ONLINE); - var identityManager = mock(IdentityManager.class); - when(identityManager.getById(anyLong())).thenReturn(device); + var cacheManager = mock(CacheManager.class); + when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); - WebDataHandler handler = new WebDataHandler(config, mock(CacheManager.class), identityManager, null, null); + WebDataHandler handler = new WebDataHandler(config, cacheManager, null, null); assertEquals( "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", diff --git a/src/test/java/org/traccar/handler/ComputedAttributesTest.java b/src/test/java/org/traccar/handler/ComputedAttributesTest.java index e3886317c..2668c4f14 100644 --- a/src/test/java/org/traccar/handler/ComputedAttributesTest.java +++ b/src/test/java/org/traccar/handler/ComputedAttributesTest.java @@ -14,7 +14,7 @@ public class ComputedAttributesTest { @Test public void testComputedAttributes() { - ComputedAttributesHandler handler = new ComputedAttributesHandler(new Config(), null, null); + ComputedAttributesHandler handler = new ComputedAttributesHandler(new Config(), null); Date date = new Date(); Position position = new Position(); diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 1440c4c30..c7f2a2cc6 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -1,20 +1,21 @@ package org.traccar.reports; import org.apache.velocity.app.VelocityEngine; +import org.junit.Before; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.database.DeviceManager; -import org.traccar.database.IdentityManager; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; +import org.traccar.reports.common.TripsConfig; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.TripReportItem; -import org.traccar.reports.common.TripsConfig; import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; import java.text.DateFormat; import java.text.ParseException; @@ -30,11 +31,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class ReportUtilsTest extends BaseTest { + + private Storage storage; + + @Before + public void init() throws StorageException { + storage = mock(Storage.class); + when(storage.getObject(any(), any())).thenReturn(mock(Device.class)); + } private Date date(String time) throws ParseException { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); @@ -53,15 +62,7 @@ public class ReportUtilsTest extends BaseTest { return position; } - - private IdentityManager mockIdentityManager() { - var device = mock(Device.class); - when(device.getName()).thenReturn("test"); - var identityManager = mock(IdentityManager.class); - when(identityManager.getById(anyLong())).thenReturn(device); - return identityManager; - } - + @Test public void testCalculateDistance() { Position startPosition = new Position(); @@ -77,7 +78,7 @@ public class ReportUtilsTest extends BaseTest { @Test public void testCalculateSpentFuel() { ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), mock(TripsConfig.class), mock(VelocityEngine.class), null); Position startPosition = new Position(); Position endPosition = new Position(); @@ -102,7 +103,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -157,7 +158,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -228,7 +229,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -279,7 +280,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -308,7 +309,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -337,7 +338,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -366,7 +367,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -391,7 +392,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( - mock(Config.class), mock(Storage.class), mock(PermissionsService.class), mockIdentityManager(), + mock(Config.class), storage, mock(PermissionsService.class), mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); -- cgit v1.2.3 From 895e89504ff0ef6fe05e2a74847f9aa582a9d270 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 11:55:35 -0700 Subject: Remove unused code --- src/main/java/org/traccar/Context.java | 3 +-- .../java/org/traccar/database/PermissionsManager.java | 18 +----------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 45d075912..dba0357c9 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -64,8 +64,7 @@ public final class Context { Main.getInjector().getInstance(DataManager.class)); permissionsManager = new PermissionsManager( - Main.getInjector().getInstance(DataManager.class), - Main.getInjector().getInstance(Storage.class)); + Main.getInjector().getInstance(DataManager.class)); } diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 9d1e5aadf..0ff20775a 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -40,7 +40,6 @@ public class PermissionsManager { private static final Logger LOGGER = LoggerFactory.getLogger(PermissionsManager.class); private final DataManager dataManager; - private final Storage storage; private final ReadWriteLock lock = new ReentrantReadWriteLock(); @@ -49,9 +48,8 @@ public class PermissionsManager { private final Map> deviceUsers = new HashMap<>(); private final Map> groupDevices = new HashMap<>(); - public PermissionsManager(DataManager dataManager, Storage storage) { + public PermissionsManager(DataManager dataManager) { this.dataManager = dataManager; - this.storage = storage; refreshDeviceAndGroupPermissions(); } @@ -71,15 +69,6 @@ public class PermissionsManager { lock.writeLock().unlock(); } - public User getUser(long userId) { - try { - return storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", userId))); - } catch (StorageException e) { - throw new RuntimeException(e); - } - } - public Set getGroupPermissions(long userId) { readLock(); try { @@ -174,11 +163,6 @@ public class PermissionsManager { } } - public boolean getUserAdmin(long userId) { - User user = getUser(userId); - return user != null && user.getAdministrator(); - } - public void refreshPermissions(Permission permission) { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) -- cgit v1.2.3 From 24140619789c88d96364673240b172bbd2ae2c82 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 12:22:21 -0700 Subject: Refactor reports dependencies --- src/main/java/org/traccar/Context.java | 1 - .../org/traccar/database/PermissionsManager.java | 4 -- .../org/traccar/reports/EventsReportProvider.java | 11 ++--- .../org/traccar/reports/RouteReportProvider.java | 11 ++--- .../org/traccar/reports/StopsReportProvider.java | 11 ++--- .../org/traccar/reports/SummaryReportProvider.java | 7 ++-- .../org/traccar/reports/TripsReportProvider.java | 11 ++--- .../org/traccar/reports/common/ReportUtils.java | 49 +++++++++++++++------- 8 files changed, 54 insertions(+), 51 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index dba0357c9..5f555858d 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -23,7 +23,6 @@ import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.storage.Storage; public final class Context { diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 0ff20775a..c52c72c4d 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -22,11 +22,7 @@ import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.User; -import org.traccar.storage.Storage; import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; import java.util.HashMap; import java.util.HashSet; diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 69d95d1be..878c0265d 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -73,11 +73,10 @@ public class EventsReportProvider { long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList result = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Collection events = getEvents(deviceId, from, to); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + Collection events = getEvents(device.getId(), from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Event event : events) { if (all || types.contains(event.getType())) { @@ -98,14 +97,13 @@ public class EventsReportProvider { OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Collection types, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList devicesEvents = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Collection events = getEvents(deviceId, from, to); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + Collection events = getEvents(device.getId(), from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Iterator iterator = events.iterator(); iterator.hasNext();) { Event event = iterator.next(); @@ -132,7 +130,6 @@ public class EventsReportProvider { } } DeviceReportSection deviceEvents = new DeviceReportSection(); - Device device = reportUtils.getDevice(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 2364cc0f3..0f618822e 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -58,11 +58,10 @@ public class RouteReportProvider { public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList result = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - result.addAll(PositionUtil.getPositions(storage, deviceId, from, to)); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + result.addAll(PositionUtil.getPositions(storage, device.getId(), from, to)); } return result; } @@ -71,14 +70,12 @@ public class RouteReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - var positions = PositionUtil.getPositions(storage, deviceId, from, to); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); DeviceReportSection deviceRoutes = new DeviceReportSection(); - Device device = reportUtils.getDevice(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 3b1f3c1fe..6e4cd74d6 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -65,11 +65,10 @@ public class StopsReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList result = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - result.addAll(detectStops(deviceId, from, to)); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + result.addAll(detectStops(device.getId(), from, to)); } return result; } @@ -78,14 +77,12 @@ public class StopsReportProvider { OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Collection stops = detectStops(deviceId, from, to); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + Collection stops = detectStops(device.getId(), from, to); DeviceReportSection deviceStops = new DeviceReportSection(); - Device device = reportUtils.getDevice(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 1f136adeb..26d79c899 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -23,6 +23,7 @@ import org.traccar.config.Keys; import org.traccar.helper.UnitsConverter; import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; +import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.SummaryReportItem; @@ -145,11 +146,11 @@ public class SummaryReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to, boolean daily) throws StorageException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList result = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Collection deviceResults = calculateSummaryResults(userId, deviceId, from, to, daily); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + Collection deviceResults = + calculateSummaryResults(userId, device.getId(), from, to, daily); for (SummaryReportItem summaryReport : deviceResults) { if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { result.add(summaryReport); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 95612ab30..7d10879b7 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -64,11 +64,10 @@ public class TripsReportProvider { public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList result = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - result.addAll(detectTrips(deviceId, from, to)); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + result.addAll(detectTrips(device.getId(), from, to)); } return result; } @@ -77,14 +76,12 @@ public class TripsReportProvider { long userId, Collection deviceIds, Collection groupIds, Date from, Date to) throws StorageException, IOException { reportUtils.checkPeriodLimit(from, to); - reportUtils.checkPermissions(userId, deviceIds, groupIds); ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); - for (long deviceId: reportUtils.getDeviceList(deviceIds, groupIds)) { - Collection trips = detectTrips(deviceId, from, to); + for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { + Collection trips = detectTrips(device.getId(), from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); - Device device = reportUtils.getDevice(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() > 0) { diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index ab009161f..3960546e9 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -26,7 +26,6 @@ import org.jxls.formula.StandardFormulaProcessor; import org.jxls.transform.Transformer; import org.jxls.transform.poi.PoiTransformer; import org.jxls.util.TransformerFactory; -import org.traccar.Context; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -62,11 +61,14 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Date; -import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; public class ReportUtils { @@ -114,22 +116,39 @@ public class ReportUtils { } } - public void checkPermissions( + public Collection getAccessibleDevices( long userId, Collection deviceIds, Collection groupIds) throws StorageException { - for (long deviceId : deviceIds) { - permissionsService.checkPermission(Device.class, userId, deviceId); - } - for (long groupId : groupIds) { - permissionsService.checkPermission(Group.class, userId, groupId); - } - } - public Collection getDeviceList(Collection deviceIds, Collection groupIds) { - Collection result = new LinkedHashSet<>(deviceIds); - for (long groupId : groupIds) { - result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); + var devices = storage.getObjects(Device.class, new Request( + new Columns.All(), + new Condition.Permission(User.class, userId, Device.class))); + var deviceById = devices.stream() + .collect(Collectors.toUnmodifiableMap(Device::getId, x -> x)); + var devicesByGroup = devices.stream() + .filter(x -> x.getGroupId() > 0) + .collect(Collectors.groupingBy(Device::getGroupId)); + + var groups = storage.getObjects(Group.class, new Request( + new Columns.All(), + new Condition.Permission(User.class, userId, Group.class))); + var groupsByGroup = groups.stream() + .filter(x -> x.getGroupId() > 0) + .collect(Collectors.groupingBy(Group::getGroupId)); + + var results = deviceIds.stream() + .map(deviceById::get) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + var groupQueue = new LinkedList<>(groupIds); + while (!groupQueue.isEmpty()) { + long groupId = groupQueue.pop(); + results.addAll(devicesByGroup.getOrDefault(groupId, Collections.emptyList())); + groupQueue.addAll(groupsByGroup.getOrDefault(groupId, Collections.emptyList()) + .stream().map(Group::getId).collect(Collectors.toUnmodifiableList())); } - return result; + + return results; } public double calculateFuel(Position firstPosition, Position lastPosition) { -- cgit v1.2.3 From b23ca6de800be9f2bbedcc4109a65f06bb245713 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 12:26:22 -0700 Subject: Remove permissions manager --- src/main/java/org/traccar/Context.java | 10 -- .../java/org/traccar/api/BaseObjectResource.java | 7 - .../traccar/api/resource/PermissionsResource.java | 13 +- .../org/traccar/database/PermissionsManager.java | 171 --------------------- .../org/traccar/session/ConnectionManager.java | 10 +- 5 files changed, 5 insertions(+), 206 deletions(-) delete mode 100644 src/main/java/org/traccar/database/PermissionsManager.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 5f555858d..246ed9f02 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -19,7 +19,6 @@ import org.traccar.config.Config; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -41,12 +40,6 @@ public final class Context { return deviceManager; } - private static PermissionsManager permissionsManager; - - public static PermissionsManager getPermissionsManager() { - return permissionsManager; - } - public static void init(String configFile) throws Exception { try { @@ -62,9 +55,6 @@ public final class Context { config, Main.getInjector().getInstance(DataManager.class)); - permissionsManager = new PermissionsManager( - Main.getInjector().getInstance(DataManager.class)); - } public static BaseObjectManager getManager(Class clazz) { diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 78aa12dbe..abfed9682 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -80,9 +80,6 @@ public abstract class BaseObjectResource extends BaseResour cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); - if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - } return Response.ok(entity).build(); } @@ -115,9 +112,6 @@ public abstract class BaseObjectResource extends BaseResour LogAction.edit(getUserId(), entity); - if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - } return Response.ok(entity).build(); } @@ -141,7 +135,6 @@ public abstract class BaseObjectResource extends BaseResour if (baseClass.equals(Group.class)) { Context.getDeviceManager().updateDeviceCache(true); } - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); } return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index b92e6e9d9..7174a3eff 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -16,7 +16,6 @@ */ package org.traccar.api.resource; -import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.LogAction; import org.traccar.model.Permission; @@ -46,7 +45,7 @@ public class PermissionsResource extends BaseResource { @Inject private CacheManager cacheManager; - private void checkPermission(Permission permission, boolean link) throws StorageException { + private void checkPermission(Permission permission) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); @@ -70,16 +69,13 @@ public class PermissionsResource extends BaseResource { checkPermissionTypes(entities); for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); - checkPermission(permission, true); + checkPermission(permission); storage.addPermission(permission); cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } - if (!entities.isEmpty()) { - Context.getPermissionsManager().refreshPermissions(new Permission(entities.get(0))); - } return Response.noContent().build(); } @@ -95,16 +91,13 @@ public class PermissionsResource extends BaseResource { checkPermissionTypes(entities); for (LinkedHashMap entity: entities) { Permission permission = new Permission(entity); - checkPermission(permission, false); + checkPermission(permission); storage.removePermission(permission); cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } - if (!entities.isEmpty()) { - Context.getPermissionsManager().refreshPermissions(new Permission(entities.get(0))); - } return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java deleted file mode 100644 index c52c72c4d..000000000 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2015 - 2022 Anton Tananaev (anton@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.database; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.model.Permission; -import org.traccar.model.User; -import org.traccar.storage.StorageException; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -public class PermissionsManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(PermissionsManager.class); - - private final DataManager dataManager; - - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - private final Map> groupPermissions = new HashMap<>(); - private final Map> devicePermissions = new HashMap<>(); - private final Map> deviceUsers = new HashMap<>(); - private final Map> groupDevices = new HashMap<>(); - - public PermissionsManager(DataManager dataManager) { - this.dataManager = dataManager; - refreshDeviceAndGroupPermissions(); - } - - protected final void readLock() { - lock.readLock().lock(); - } - - protected final void readUnlock() { - lock.readLock().unlock(); - } - - protected final void writeLock() { - lock.writeLock().lock(); - } - - protected final void writeUnlock() { - lock.writeLock().unlock(); - } - - public Set getGroupPermissions(long userId) { - readLock(); - try { - if (!groupPermissions.containsKey(userId)) { - groupPermissions.put(userId, new HashSet<>()); - } - return groupPermissions.get(userId); - } finally { - readUnlock(); - } - } - - public Set getDevicePermissions(long userId) { - readLock(); - try { - if (!devicePermissions.containsKey(userId)) { - devicePermissions.put(userId, new HashSet<>()); - } - return devicePermissions.get(userId); - } finally { - readUnlock(); - } - } - - private Set getAllDeviceUsers(long deviceId) { - readLock(); - try { - if (!deviceUsers.containsKey(deviceId)) { - deviceUsers.put(deviceId, new HashSet<>()); - } - return deviceUsers.get(deviceId); - } finally { - readUnlock(); - } - } - - public Set getGroupDevices(long groupId) { - readLock(); - try { - if (!groupDevices.containsKey(groupId)) { - groupDevices.put(groupId, new HashSet<>()); - } - return groupDevices.get(groupId); - } finally { - readUnlock(); - } - } - - public final void refreshDeviceAndGroupPermissions() { - writeLock(); - try { - groupPermissions.clear(); - devicePermissions.clear(); - try { - var groups = dataManager.getObjects(Group.class); - GroupTree groupTree = new GroupTree(groups, Context.getDeviceManager().getAllDevices()); - for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) { - Set userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId()); - Set userDevicePermissions = getDevicePermissions(groupPermission.getOwnerId()); - userGroupPermissions.add(groupPermission.getPropertyId()); - for (Group group : groupTree.getGroups(groupPermission.getPropertyId())) { - userGroupPermissions.add(group.getId()); - } - for (Device device : groupTree.getDevices(groupPermission.getPropertyId())) { - userDevicePermissions.add(device.getId()); - } - } - - for (Permission devicePermission : dataManager.getPermissions(User.class, Device.class)) { - getDevicePermissions(devicePermission.getOwnerId()).add(devicePermission.getPropertyId()); - } - - groupDevices.clear(); - for (var group : groups) { - for (Device device : groupTree.getDevices(group.getId())) { - getGroupDevices(group.getId()).add(device.getId()); - } - } - - } catch (StorageException | ClassNotFoundException error) { - LOGGER.warn("Refresh device permissions error", error); - } - - deviceUsers.clear(); - for (Map.Entry> entry : devicePermissions.entrySet()) { - for (long deviceId : entry.getValue()) { - getAllDeviceUsers(deviceId).add(entry.getKey()); - } - } - } finally { - writeUnlock(); - } - } - - public void refreshPermissions(Permission permission) { - if (permission.getOwnerClass().equals(User.class)) { - if (permission.getPropertyClass().equals(Device.class) - || permission.getPropertyClass().equals(Group.class)) { - refreshDeviceAndGroupPermissions(); - } - } - } - -} diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 3fa467b57..38d82e848 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -164,16 +164,10 @@ public class ConnectionManager { try { device.setId(storage.addObject(device, new Request(new Columns.Exclude("id")))); - - LOGGER.info("Automatically registered device " + uniqueId); - - if (defaultGroupId != 0) { - Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); - } - + LOGGER.info("Automatically registered " + uniqueId); return device; } catch (StorageException e) { - LOGGER.warn("Automatic device registration error", e); + LOGGER.warn("Automatic registration failed", e); return null; } } -- cgit v1.2.3 From 3f1c4e293f7d7d267a64fa9561fe77e9ba02477b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 12:26:47 -0700 Subject: Remove unused code --- src/main/java/org/traccar/database/DataManager.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index f80f429e1..bfc79eb77 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -17,8 +17,6 @@ package org.traccar.database; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Permission; -import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -44,21 +42,10 @@ public class DataManager { new Condition.Equals("id", "id"))); } - public Collection getLatestPositions() throws StorageException { - return storage.getObjects(Position.class, new Request( - new Columns.All(), - new Condition.LatestPositions())); - } - public Server getServer() throws StorageException { return storage.getObject(Server.class, new Request(new Columns.All())); } - public Collection getPermissions(Class owner, Class property) - throws StorageException, ClassNotFoundException { - return storage.getPermissions(owner, property); - } - public Collection getObjects(Class clazz) throws StorageException { return storage.getObjects(clazz, new Request(new Columns.All())); } -- cgit v1.2.3 From 589582c7ecc0d1cd5321cb6e9f4b823284369498 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 12:30:26 -0700 Subject: Simplify storage interface --- .../java/org/traccar/api/security/PermissionsService.java | 4 +++- src/main/java/org/traccar/storage/Storage.java | 12 ------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index f39ded2b7..ea7a9d572 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -100,7 +100,9 @@ public class PermissionsService { } else if (clazz.equals(Device.class)) { denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly(); if (addition) { - int deviceCount = storage.getPermissions(User.class, userId, Device.class).size(); + int deviceCount = storage.getObjects(Device.class, new Request( + new Columns.Include("id"), + new Condition.Permission(User.class, userId, Device.class))).size(); denied = deviceCount >= getUser(userId).getDeviceLimit(); } } else if (clazz.equals(Command.class)) { diff --git a/src/main/java/org/traccar/storage/Storage.java b/src/main/java/org/traccar/storage/Storage.java index 62dba0165..55f5c22c0 100644 --- a/src/main/java/org/traccar/storage/Storage.java +++ b/src/main/java/org/traccar/storage/Storage.java @@ -45,18 +45,6 @@ public abstract class Storage { return getPermissions(ownerClass, 0, propertyClass, 0); } - public List getPermissions( - Class ownerClass, long ownerId, - Class propertyClass) throws StorageException { - return getPermissions(ownerClass, ownerId, propertyClass, 0); - } - - public List getPermissions( - Class ownerClass, - Class propertyClass, long propertyId) throws StorageException { - return getPermissions(ownerClass, 0, propertyClass, propertyId); - } - public T getObject(Class clazz, Request request) throws StorageException { var objects = getObjects(clazz, request); return objects.isEmpty() ? null : objects.get(0); -- cgit v1.2.3 From 3a293661cd2900c115cfea6037c02d659c57aa52 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:19:53 -0700 Subject: Move device status --- src/main/java/org/traccar/Context.java | 4 +-- src/main/java/org/traccar/config/Keys.java | 8 ----- .../java/org/traccar/database/DataManager.java | 7 ---- .../java/org/traccar/database/DeviceManager.java | 41 ++-------------------- .../traccar/handler/events/MotionEventHandler.java | 13 +++---- .../handler/events/OverspeedEventHandler.java | 12 +++---- .../org/traccar/reports/common/ReportUtils.java | 8 ++--- .../schedule/TaskDeviceInactivityCheck.java | 30 +++++++++++----- .../org/traccar/session/ConnectionManager.java | 17 +++++++-- .../java/org/traccar/reports/ReportUtilsTest.java | 18 +++++----- 10 files changed, 62 insertions(+), 96 deletions(-) diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 246ed9f02..c89d39f4c 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -51,9 +51,7 @@ public final class Context { throw e; } - deviceManager = new DeviceManager( - config, - Main.getInjector().getInstance(DataManager.class)); + deviceManager = new DeviceManager(Main.getInjector().getInstance(DataManager.class)); } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 5909ae517..6eb61607e 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -476,14 +476,6 @@ public final class Keys { "database.registerUnknown.defaultGroupId", List.of(KeyType.CONFIG)); - /** - * Minimum device refresh timeout in seconds. Default timeout is 5 minutes. - */ - public static final ConfigKey DATABASE_REFRESH_DELAY = new LongConfigKey( - "database.refreshDelay", - List.of(KeyType.CONFIG), - 300L); - /** * Store empty messages as positions. For example, heartbeats. */ diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index bfc79eb77..398c63892 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -16,7 +16,6 @@ package org.traccar.database; import org.traccar.model.BaseModel; -import org.traccar.model.Device; import org.traccar.model.Server; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -36,12 +35,6 @@ public class DataManager { this.storage = storage; } - public void updateDeviceStatus(Device device) throws StorageException { - storage.updateObject(device, new Request( - new Columns.Include("lastUpdate"), - new Condition.Equals("id", "id"))); - } - public Server getServer() throws StorageException { return storage.getObject(Server.class, new Request(new Columns.All())); } diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index d6c442f10..7a472c2d4 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -15,34 +15,22 @@ */ package org.traccar.database; -import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.model.Device; -import org.traccar.session.DeviceState; -import org.traccar.storage.StorageException; -import java.util.Collection; -import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; public class DeviceManager extends BaseObjectManager { - private final long dataRefreshDelay; - private final AtomicLong devicesLastUpdate = new AtomicLong(); - private final Map deviceStates = new ConcurrentHashMap<>(); - - public DeviceManager(Config config, DataManager dataManager) { + public DeviceManager(DataManager dataManager) { super(dataManager, Device.class); - dataRefreshDelay = config.getLong(Keys.DATABASE_REFRESH_DELAY) * 1000; } public void updateDeviceCache(boolean force) { long lastUpdate = devicesLastUpdate.get(); - if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) + if ((force || System.currentTimeMillis() - lastUpdate > 300000L) && devicesLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { refreshItems(); } @@ -58,10 +46,6 @@ public class DeviceManager extends BaseObjectManager { return result; } - public Collection getAllDevices() { - return getItems(getAllItems()); - } - @Override protected void updateCachedItem(Device device) { Device cachedDevice = getById(device.getId()); @@ -84,25 +68,4 @@ public class DeviceManager extends BaseObjectManager { } } - public void updateDeviceStatus(Device device) throws StorageException { - getDataManager().updateDeviceStatus(device); - Device cachedDevice = getById(device.getId()); - if (cachedDevice != null) { - cachedDevice.setStatus(device.getStatus()); - } - } - - public DeviceState getDeviceState(long deviceId) { - DeviceState deviceState = deviceStates.get(deviceId); - if (deviceState == null) { - deviceState = new DeviceState(); - deviceStates.put(deviceId, deviceState); - } - return deviceState; - } - - public void setDeviceState(long deviceId, DeviceState deviceState) { - deviceStates.put(deviceId, deviceState); - } - } diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 724e9bf15..bc9d5f722 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -17,12 +17,12 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; -import org.traccar.database.DeviceManager; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.common.TripsConfig; +import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceState; import org.traccar.session.cache.CacheManager; @@ -34,13 +34,14 @@ import java.util.Map; public class MotionEventHandler extends BaseEventHandler { private final CacheManager cacheManager; - private final DeviceManager deviceManager; + private final ConnectionManager connectionManager; private final TripsConfig tripsConfig; @Inject - public MotionEventHandler(CacheManager cacheManager, DeviceManager deviceManager, TripsConfig tripsConfig) { + public MotionEventHandler( + CacheManager cacheManager, ConnectionManager connectionManager, TripsConfig tripsConfig) { this.cacheManager = cacheManager; - this.deviceManager = deviceManager; + this.connectionManager = connectionManager; this.tripsConfig = tripsConfig; } @@ -123,14 +124,14 @@ public class MotionEventHandler extends BaseEventHandler { } Map result = null; - DeviceState deviceState = deviceManager.getDeviceState(deviceId); + DeviceState deviceState = connectionManager.getDeviceState(deviceId); if (deviceState.getMotionState() == null) { deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); } else { result = updateMotionState(deviceState, position); } - deviceManager.setDeviceState(deviceId, deviceState); + connectionManager.setDeviceState(deviceId, deviceState); return result; } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 6de56d11e..7f3675308 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -22,10 +22,10 @@ import java.util.Map; import io.netty.channel.ChannelHandler; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.DeviceManager; import org.traccar.helper.model.AttributeUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; +import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -39,7 +39,7 @@ public class OverspeedEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_SPEED = "speed"; - private final DeviceManager deviceManager; + private final ConnectionManager connectionManager; private final CacheManager cacheManager; private final boolean notRepeat; @@ -47,8 +47,8 @@ public class OverspeedEventHandler extends BaseEventHandler { private final boolean preferLowest; @Inject - public OverspeedEventHandler(Config config, DeviceManager deviceManager, CacheManager cacheManager) { - this.deviceManager = deviceManager; + public OverspeedEventHandler(Config config, ConnectionManager connectionManager, CacheManager cacheManager) { + this.connectionManager = connectionManager; this.cacheManager = cacheManager; notRepeat = config.getBoolean(Keys.EVENT_OVERSPEED_NOT_REPEAT); minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000; @@ -157,7 +157,7 @@ public class OverspeedEventHandler extends BaseEventHandler { } Map result = null; - DeviceState deviceState = deviceManager.getDeviceState(deviceId); + DeviceState deviceState = connectionManager.getDeviceState(deviceId); if (deviceState.getOverspeedState() == null) { deviceState.setOverspeedState(position.getSpeed() > speedLimit); @@ -166,7 +166,7 @@ public class OverspeedEventHandler extends BaseEventHandler { result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); } - deviceManager.setDeviceState(deviceId, deviceState); + connectionManager.setDeviceState(deviceId, deviceState); return result; } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 3960546e9..f5f2cd3df 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -29,7 +29,6 @@ import org.jxls.util.TransformerFactory; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.DeviceManager; import org.traccar.geocoder.Geocoder; import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; @@ -75,7 +74,6 @@ public class ReportUtils { private final Config config; private final Storage storage; private final PermissionsService permissionsService; - private final DeviceManager deviceManager; private final TripsConfig tripsConfig; private final VelocityEngine velocityEngine; private final Geocoder geocoder; @@ -83,12 +81,10 @@ public class ReportUtils { @Inject public ReportUtils( Config config, Storage storage, PermissionsService permissionsService, - DeviceManager deviceManager, TripsConfig tripsConfig, VelocityEngine velocityEngine, - @Nullable Geocoder geocoder) { + TripsConfig tripsConfig, VelocityEngine velocityEngine, @Nullable Geocoder geocoder) { this.config = config; this.storage = storage; this.permissionsService = permissionsService; - this.deviceManager = deviceManager; this.tripsConfig = tripsConfig; this.velocityEngine = velocityEngine; this.geocoder = geocoder; @@ -369,7 +365,7 @@ public class ReportUtils { ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); - MotionEventHandler motionHandler = new MotionEventHandler(null, deviceManager, tripsConfig); + MotionEventHandler motionHandler = new MotionEventHandler(null, null, tripsConfig); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; diff --git a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java index f2ed3c3b3..57c64dc5b 100644 --- a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java +++ b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java @@ -15,11 +15,16 @@ */ package org.traccar.schedule; -import org.traccar.database.DeviceManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.database.NotificationManager; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.HashMap; @@ -29,18 +34,20 @@ import java.util.concurrent.TimeUnit; public class TaskDeviceInactivityCheck implements ScheduleTask { + private static final Logger LOGGER = LoggerFactory.getLogger(TaskDeviceInactivityCheck.class); + public static final String ATTRIBUTE_DEVICE_INACTIVITY_START = "deviceInactivityStart"; public static final String ATTRIBUTE_DEVICE_INACTIVITY_PERIOD = "deviceInactivityPeriod"; public static final String ATTRIBUTE_LAST_UPDATE = "lastUpdate"; private static final long CHECK_PERIOD_MINUTES = 15; - private final DeviceManager deviceManager; + private final Storage storage; private final NotificationManager notificationManager; @Inject - public TaskDeviceInactivityCheck(DeviceManager deviceManager, NotificationManager notificationManager) { - this.deviceManager = deviceManager; + public TaskDeviceInactivityCheck(Storage storage, NotificationManager notificationManager) { + this.storage = storage; this.notificationManager = notificationManager; } @@ -55,12 +62,17 @@ public class TaskDeviceInactivityCheck implements ScheduleTask { long checkPeriod = TimeUnit.MINUTES.toMillis(CHECK_PERIOD_MINUTES); Map events = new HashMap<>(); - for (Device device : deviceManager.getAllDevices()) { - if (device.getLastUpdate() != null && checkDevice(device, currentTime, checkPeriod)) { - Event event = new Event(Event.TYPE_DEVICE_INACTIVE, device.getId()); - event.set(ATTRIBUTE_LAST_UPDATE, device.getLastUpdate().getTime()); - events.put(event, null); + + try { + for (Device device : storage.getObjects(Device.class, new Request(new Columns.All()))) { + if (device.getLastUpdate() != null && checkDevice(device, currentTime, checkPeriod)) { + Event event = new Event(Event.TYPE_DEVICE_INACTIVE, device.getId()); + event.set(ATTRIBUTE_LAST_UPDATE, device.getLastUpdate().getTime()); + events.put(event, null); + } } + } catch (StorageException e) { + LOGGER.warn("Get devices error", e); } notificationManager.updateEvents(events); diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 38d82e848..cead771c9 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -20,7 +20,6 @@ import io.netty.util.Timeout; import io.netty.util.Timer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.Main; import org.traccar.Protocol; import org.traccar.config.Config; @@ -63,6 +62,8 @@ public class ConnectionManager { private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); + private final Map deviceStates = new ConcurrentHashMap<>(); + private final Config config; private final CacheManager cacheManager; private final Storage storage; @@ -256,7 +257,9 @@ public class ConnectionManager { } try { - Context.getDeviceManager().updateDeviceStatus(device); + storage.updateObject(device, new Request( + new Columns.Include("lastUpdate"), + new Condition.Equals("id", "id"))); } catch (StorageException e) { LOGGER.warn("Update device status error", e); } @@ -264,8 +267,16 @@ public class ConnectionManager { updateDevice(device); } + public DeviceState getDeviceState(long deviceId) { + return deviceStates.computeIfAbsent(deviceId, x -> new DeviceState()); + } + + public void setDeviceState(long deviceId, DeviceState deviceState) { + deviceStates.put(deviceId, deviceState); + } + public Map updateDeviceState(long deviceId) { - DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); + DeviceState deviceState = getDeviceState(deviceId); Map result = new HashMap<>(); Map event = Main.getInjector() diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index c7f2a2cc6..707d9d211 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -79,7 +79,7 @@ public class ReportUtilsTest extends BaseTest { public void testCalculateSpentFuel() { ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), mock(TripsConfig.class), mock(VelocityEngine.class), null); + mock(TripsConfig.class), mock(VelocityEngine.class), null); Position startPosition = new Position(); Position endPosition = new Position(); assertEquals(reportUtils.calculateFuel(startPosition, endPosition), 0.0, 0.01); @@ -104,7 +104,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -159,7 +159,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, true, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -230,7 +230,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 180000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); @@ -281,7 +281,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -310,7 +310,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -339,7 +339,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -368,7 +368,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); @@ -393,7 +393,7 @@ public class ReportUtilsTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 200000, 200000, 900000, false, false, 0.01); ReportUtils reportUtils = new ReportUtils( mock(Config.class), storage, mock(PermissionsService.class), - mock(DeviceManager.class), tripsConfig, mock(VelocityEngine.class), null); + tripsConfig, mock(VelocityEngine.class), null); Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); -- cgit v1.2.3 From c79c71a734da5cb4c84dd660744e58675b1d6fb7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:23:16 -0700 Subject: Remove device manager --- src/main/java/org/traccar/Context.java | 20 --- src/main/java/org/traccar/MainModule.java | 6 - .../java/org/traccar/api/BaseObjectResource.java | 36 +---- .../org/traccar/database/BaseObjectManager.java | 174 --------------------- .../java/org/traccar/database/DeviceManager.java | 71 --------- .../org/traccar/database/SimpleObjectManager.java | 27 ---- .../java/org/traccar/reports/ReportUtilsTest.java | 1 - 7 files changed, 5 insertions(+), 330 deletions(-) delete mode 100644 src/main/java/org/traccar/database/BaseObjectManager.java delete mode 100644 src/main/java/org/traccar/database/DeviceManager.java delete mode 100644 src/main/java/org/traccar/database/SimpleObjectManager.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index c89d39f4c..583ee460b 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -16,12 +16,7 @@ package org.traccar; import org.traccar.config.Config; -import org.traccar.database.BaseObjectManager; -import org.traccar.database.DataManager; -import org.traccar.database.DeviceManager; import org.traccar.helper.Log; -import org.traccar.model.BaseModel; -import org.traccar.model.Device; public final class Context { @@ -34,12 +29,6 @@ public final class Context { return config; } - private static DeviceManager deviceManager; - - public static DeviceManager getDeviceManager() { - return deviceManager; - } - public static void init(String configFile) throws Exception { try { @@ -51,15 +40,6 @@ public final class Context { throw e; } - deviceManager = new DeviceManager(Main.getInjector().getInstance(DataManager.class)); - - } - - public static BaseObjectManager getManager(Class clazz) { - if (clazz.equals(Device.class)) { - return (BaseObjectManager) deviceManager; - } - return null; } } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index d57ee5d38..439dcd1d9 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,7 +30,6 @@ import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.DeviceManager; import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; @@ -113,11 +112,6 @@ public class MainModule extends AbstractModule { (ContextResolver) clazz -> Main.getInjector().getInstance(ObjectMapper.class)); } - @Provides - public static DeviceManager provideDeviceManager() { - return Context.getDeviceManager(); - } - @Singleton @Provides public static SmsManager provideSmsManager(Config config, Client client) { diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index abfed9682..35ff04bf3 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -16,11 +16,8 @@ */ package org.traccar.api; -import org.traccar.Context; -import org.traccar.database.BaseObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; -import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.User; @@ -67,15 +64,8 @@ public abstract class BaseObjectResource extends BaseResour public Response add(T entity) throws StorageException { permissionsService.checkEdit(getUserId(), entity, true); - BaseObjectManager manager = Context.getManager(baseClass); - if (manager != null) { - manager.addItem(entity); - } else { - entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); - } - + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); LogAction.create(getUserId(), entity); - storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); @@ -100,16 +90,10 @@ public abstract class BaseObjectResource extends BaseResour } } - BaseObjectManager manager = Context.getManager(baseClass); - if (manager != null) { - manager.updateItem(entity); - } else { - storage.updateObject(entity, new Request( - new Columns.Exclude("id"), - new Condition.Equals("id", "id"))); - } + storage.updateObject(entity, new Request( + new Columns.Exclude("id"), + new Condition.Equals("id", "id"))); cacheManager.updateOrInvalidate(entity); - LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); @@ -121,21 +105,11 @@ public abstract class BaseObjectResource extends BaseResour permissionsService.checkEdit(getUserId(), baseClass, false); permissionsService.checkPermission(baseClass, getUserId(), id); - BaseObjectManager manager = Context.getManager(baseClass); - if (manager != null) { - manager.removeItem(id); - } else { - storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); - } + storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); cacheManager.invalidate(baseClass, id); LogAction.remove(getUserId(), baseClass, id); - if (baseClass.equals(Group.class) || baseClass.equals(Device.class) || baseClass.equals(User.class)) { - if (baseClass.equals(Group.class)) { - Context.getDeviceManager().updateDeviceCache(true); - } - } return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/database/BaseObjectManager.java b/src/main/java/org/traccar/database/BaseObjectManager.java deleted file mode 100644 index c94053985..000000000 --- a/src/main/java/org/traccar/database/BaseObjectManager.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.database; - -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.model.BaseModel; -import org.traccar.storage.StorageException; - -public class BaseObjectManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(BaseObjectManager.class); - - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - private final DataManager dataManager; - - private final Class baseClass; - private Map items; - - protected BaseObjectManager(DataManager dataManager, Class baseClass) { - this.dataManager = dataManager; - this.baseClass = baseClass; - refreshItems(); - } - - protected final void readLock() { - lock.readLock().lock(); - } - - protected final void readUnlock() { - lock.readLock().unlock(); - } - - protected final void writeLock() { - lock.writeLock().lock(); - } - - protected final void writeUnlock() { - lock.writeLock().unlock(); - } - - protected final DataManager getDataManager() { - return dataManager; - } - - public T getById(long itemId) { - try { - readLock(); - return items.get(itemId); - } finally { - readUnlock(); - } - } - - public void refreshItems() { - if (dataManager != null) { - try { - writeLock(); - Collection databaseItems = dataManager.getObjects(baseClass); - if (items == null) { - items = new ConcurrentHashMap<>(databaseItems.size()); - } - Set databaseItemIds = new HashSet<>(); - for (T item : databaseItems) { - databaseItemIds.add(item.getId()); - if (items.containsKey(item.getId())) { - updateCachedItem(item); - } else { - addNewItem(item); - } - } - for (Long cachedItemId : items.keySet()) { - if (!databaseItemIds.contains(cachedItemId)) { - removeCachedItem(cachedItemId); - } - } - } catch (StorageException error) { - LOGGER.warn("Error refreshing items", error); - } finally { - writeUnlock(); - } - } - } - - protected void addNewItem(T item) { - try { - writeLock(); - items.put(item.getId(), item); - } finally { - writeUnlock(); - } - } - - public void addItem(T item) throws StorageException { - dataManager.addObject(item); - addNewItem(item); - } - - protected void updateCachedItem(T item) { - try { - writeLock(); - items.put(item.getId(), item); - } finally { - writeUnlock(); - } - } - - public void updateItem(T item) throws StorageException { - dataManager.updateObject(item); - updateCachedItem(item); - } - - protected void removeCachedItem(long itemId) { - try { - writeLock(); - items.remove(itemId); - } finally { - writeUnlock(); - } - } - - public void removeItem(long itemId) throws StorageException { - BaseModel item = getById(itemId); - if (item != null) { - dataManager.removeObject(baseClass, itemId); - removeCachedItem(itemId); - } - } - - public final Collection getItems(Set itemIds) { - Collection result = new LinkedList<>(); - for (long itemId : itemIds) { - T item = getById(itemId); - if (item != null) { - result.add(item); - } - } - return result; - } - - public Set getAllItems() { - try { - readLock(); - return items.keySet(); - } finally { - readUnlock(); - } - } - -} diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java deleted file mode 100644 index 7a472c2d4..000000000 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2016 - 2022 Anton Tananaev (anton@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.database; - -import org.traccar.model.Device; - -import java.util.Set; -import java.util.concurrent.atomic.AtomicLong; - -public class DeviceManager extends BaseObjectManager { - - private final AtomicLong devicesLastUpdate = new AtomicLong(); - - public DeviceManager(DataManager dataManager) { - super(dataManager, Device.class); - } - - public void updateDeviceCache(boolean force) { - long lastUpdate = devicesLastUpdate.get(); - if ((force || System.currentTimeMillis() - lastUpdate > 300000L) - && devicesLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { - refreshItems(); - } - } - - @Override - public Set getAllItems() { - Set result = super.getAllItems(); - if (result.isEmpty()) { - updateDeviceCache(true); - result = super.getAllItems(); - } - return result; - } - - @Override - protected void updateCachedItem(Device device) { - Device cachedDevice = getById(device.getId()); - cachedDevice.setName(device.getName()); - cachedDevice.setGroupId(device.getGroupId()); - cachedDevice.setCategory(device.getCategory()); - cachedDevice.setContact(device.getContact()); - cachedDevice.setPhone(device.getPhone()); - cachedDevice.setModel(device.getModel()); - cachedDevice.setDisabled(device.getDisabled()); - cachedDevice.setAttributes(device.getAttributes()); - cachedDevice.setUniqueId(device.getUniqueId()); - } - - @Override - protected void removeCachedItem(long deviceId) { - Device cachedDevice = getById(deviceId); - if (cachedDevice != null) { - super.removeCachedItem(deviceId); - } - } - -} diff --git a/src/main/java/org/traccar/database/SimpleObjectManager.java b/src/main/java/org/traccar/database/SimpleObjectManager.java deleted file mode 100644 index 8bb22b8a8..000000000 --- a/src/main/java/org/traccar/database/SimpleObjectManager.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.database; - -import org.traccar.model.BaseModel; - -public abstract class SimpleObjectManager extends BaseObjectManager { - - protected SimpleObjectManager(DataManager dataManager, Class baseClass) { - super(dataManager, baseClass); - } - -} diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index 707d9d211..dfb2ef05c 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -6,7 +6,6 @@ import org.junit.Test; import org.traccar.BaseTest; import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; -import org.traccar.database.DeviceManager; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; -- cgit v1.2.3 From 6fe1f8ed83680204fe7ec50382588dbe82fec1ba Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:26:15 -0700 Subject: Remove data manager --- .../java/org/traccar/database/DataManager.java | 60 ---------------------- .../org/traccar/database/StatisticsManager.java | 11 ++-- .../org/traccar/handler/DefaultDataHandler.java | 12 +++-- 3 files changed, 14 insertions(+), 69 deletions(-) delete mode 100644 src/main/java/org/traccar/database/DataManager.java diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java deleted file mode 100644 index 398c63892..000000000 --- a/src/main/java/org/traccar/database/DataManager.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012 - 2022 Anton Tananaev (anton@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.database; - -import org.traccar.model.BaseModel; -import org.traccar.model.Server; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import javax.inject.Inject; -import java.util.Collection; - -public class DataManager { - - private final Storage storage; - - @Inject - public DataManager(Storage storage) { - this.storage = storage; - } - - public Server getServer() throws StorageException { - return storage.getObject(Server.class, new Request(new Columns.All())); - } - - public Collection getObjects(Class clazz) throws StorageException { - return storage.getObjects(clazz, new Request(new Columns.All())); - } - - public void addObject(BaseModel entity) throws StorageException { - entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); - } - - public void updateObject(BaseModel entity) throws StorageException { - storage.updateObject(entity, new Request( - new Columns.Exclude("id"), - new Condition.Equals("id", "id"))); - } - - public void removeObject(Class clazz, long entityId) throws StorageException { - storage.removeObject(clazz, new Request(new Condition.Equals("id", "id", entityId))); - } - -} diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index d5a179cbe..e0995dabc 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -23,7 +23,10 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.DateUtil; import org.traccar.model.Statistics; +import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.inject.Singleton; @@ -46,7 +49,7 @@ public class StatisticsManager { private static final int SPLIT_MODE = Calendar.DAY_OF_MONTH; private final Config config; - private final DataManager dataManager; + private final Storage storage; private final Client client; private final ObjectMapper objectMapper; @@ -64,9 +67,9 @@ public class StatisticsManager { private int geolocationRequests; @Inject - public StatisticsManager(Config config, DataManager dataManager, Client client, ObjectMapper objectMapper) { + public StatisticsManager(Config config, Storage storage, Client client, ObjectMapper objectMapper) { this.config = config; - this.dataManager = dataManager; + this.storage = storage; this.client = client; this.objectMapper = objectMapper; } @@ -107,7 +110,7 @@ public class StatisticsManager { } try { - dataManager.addObject(statistics); + storage.addObject(statistics, new Request(new Columns.Exclude("id"))); } catch (StorageException e) { LOGGER.warn("Error saving statistics", e); } diff --git a/src/main/java/org/traccar/handler/DefaultDataHandler.java b/src/main/java/org/traccar/handler/DefaultDataHandler.java index c2adfd799..f6a20628b 100644 --- a/src/main/java/org/traccar/handler/DefaultDataHandler.java +++ b/src/main/java/org/traccar/handler/DefaultDataHandler.java @@ -19,8 +19,10 @@ import io.netty.channel.ChannelHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.BaseDataHandler; -import org.traccar.database.DataManager; import org.traccar.model.Position; +import org.traccar.storage.Storage; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; import javax.inject.Inject; @@ -29,18 +31,18 @@ public class DefaultDataHandler extends BaseDataHandler { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDataHandler.class); - private final DataManager dataManager; + private final Storage storage; @Inject - public DefaultDataHandler(DataManager dataManager) { - this.dataManager = dataManager; + public DefaultDataHandler(Storage storage) { + this.storage = storage; } @Override protected Position handlePosition(Position position) { try { - dataManager.addObject(position); + position.setId(storage.addObject(position, new Request(new Columns.Exclude("id")))); } catch (Exception error) { LOGGER.warn("Failed to store position", error); } -- cgit v1.2.3 From e65bfeab8dafb02c21b360b4970d5d94013f53f6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:36:32 -0700 Subject: Finally remove context --- src/main/java/org/traccar/Context.java | 45 ---------------------- src/main/java/org/traccar/Main.java | 3 +- src/main/java/org/traccar/MainModule.java | 22 ++++++++++- src/main/java/org/traccar/TrackerClient.java | 2 +- src/main/java/org/traccar/TrackerServer.java | 2 +- .../java/org/traccar/api/AsyncSocketServlet.java | 9 +++-- .../java/org/traccar/api/CorsResponseFilter.java | 14 +++++-- 7 files changed, 39 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/org/traccar/Context.java diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java deleted file mode 100644 index 583ee460b..000000000 --- a/src/main/java/org/traccar/Context.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2015 - 2022 Anton Tananaev (anton@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; - -import org.traccar.config.Config; -import org.traccar.helper.Log; - -public final class Context { - - private Context() { - } - - private static Config config; - - public static Config getConfig() { - return config; - } - - public static void init(String configFile) throws Exception { - - try { - config = new Config(configFile); - Log.setupLogger(config); - } catch (Exception e) { - config = new Config(); - Log.setupDefaultLogger(); - throw e; - } - - } - -} diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index bf69b565d..6a968ac7e 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -115,8 +115,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new WebModule()); - Context.init(configFile); + injector = Guice.createInjector(new MainModule(configFile), new DatabaseModule(), new WebModule()); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); LOGGER.info("Starting server..."); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 439dcd1d9..7dcc91f32 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -22,6 +22,8 @@ import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Provides; import com.google.inject.Scopes; +import com.google.inject.name.Named; +import com.google.inject.name.Names; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; import org.apache.velocity.app.VelocityEngine; @@ -59,6 +61,7 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; @@ -83,8 +86,15 @@ import java.util.Properties; public class MainModule extends AbstractModule { + private final String configFile; + + public MainModule(String configFile) { + this.configFile = configFile; + } + @Override protected void configure() { + bindConstant().annotatedWith(Names.named("configFile")).to(configFile); bind(Storage.class).to(DatabaseStorage.class); bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); } @@ -101,9 +111,17 @@ public class MainModule extends AbstractModule { return objectMapper; } + @Singleton @Provides - public static Config provideConfig() { - return Context.getConfig(); + public static Config provideConfig(@Named("configFile") String configFile) throws Exception { + try { + Config config = new Config(configFile); + Log.setupLogger(config); + return config; + } catch (Exception e) { + Log.setupDefaultLogger(); + throw e; + } } @Provides diff --git a/src/main/java/org/traccar/TrackerClient.java b/src/main/java/org/traccar/TrackerClient.java index 5a3c38212..2e8a73677 100644 --- a/src/main/java/org/traccar/TrackerClient.java +++ b/src/main/java/org/traccar/TrackerClient.java @@ -54,7 +54,7 @@ public abstract class TrackerClient implements TrackerConnector { } public TrackerClient(String protocol) { - Config config = Context.getConfig(); + Config config = Main.getInjector().getInstance(Config.class); secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); interval = config.getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol)); diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index dd83ca6b0..ccf3cd640 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -58,7 +58,7 @@ public abstract class TrackerServer implements TrackerConnector { public TrackerServer(boolean datagram, String protocol) { this.datagram = datagram; - Config config = Context.getConfig(); + Config config = Main.getInjector().getInstance(Config.class); secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); address = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 7d9fdf0ed..40e1551a1 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -18,8 +18,8 @@ package org.traccar.api; import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; -import org.traccar.Context; import org.traccar.api.resource.SessionResource; +import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.session.ConnectionManager; import org.traccar.storage.Storage; @@ -32,12 +32,15 @@ import java.time.Duration; @Singleton public class AsyncSocketServlet extends JettyWebSocketServlet { + private final Config config; private final ObjectMapper objectMapper; private final ConnectionManager connectionManager; private final Storage storage; @Inject - public AsyncSocketServlet(ObjectMapper objectMapper, ConnectionManager connectionManager, Storage storage) { + public AsyncSocketServlet( + Config config, ObjectMapper objectMapper, ConnectionManager connectionManager, Storage storage) { + this.config = config; this.objectMapper = objectMapper; this.connectionManager = connectionManager; this.storage = storage; @@ -45,7 +48,7 @@ public class AsyncSocketServlet extends JettyWebSocketServlet { @Override public void configure(JettyWebSocketServletFactory factory) { - factory.setIdleTimeout(Duration.ofMillis(Context.getConfig().getLong(Keys.WEB_TIMEOUT))); + factory.setIdleTimeout(Duration.ofMillis(config.getLong(Keys.WEB_TIMEOUT))); factory.setCreator((req, resp) -> { if (req.getSession() != null) { long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); diff --git a/src/main/java/org/traccar/api/CorsResponseFilter.java b/src/main/java/org/traccar/api/CorsResponseFilter.java index 91aea5718..5375e207f 100644 --- a/src/main/java/org/traccar/api/CorsResponseFilter.java +++ b/src/main/java/org/traccar/api/CorsResponseFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,9 +16,10 @@ package org.traccar.api; import io.netty.handler.codec.http.HttpHeaderNames; -import org.traccar.Context; +import org.traccar.config.Config; import org.traccar.config.Keys; +import javax.inject.Inject; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; @@ -26,6 +27,13 @@ import java.io.IOException; public class CorsResponseFilter implements ContainerResponseFilter { + private final String allowed; + + @Inject + public CorsResponseFilter(Config config) { + allowed = config.getString(Keys.WEB_ORIGIN); + } + private static final String ORIGIN_ALL = "*"; private static final String HEADERS_ALL = "origin, content-type, accept, authorization"; private static final String METHODS_ALL = "GET, POST, PUT, DELETE, OPTIONS"; @@ -46,8 +54,6 @@ public class CorsResponseFilter implements ContainerResponseFilter { if (!response.getHeaders().containsKey(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN.toString())) { String origin = request.getHeaderString(HttpHeaderNames.ORIGIN.toString()); - String allowed = Context.getConfig().getString(Keys.WEB_ORIGIN); - if (origin == null) { response.getHeaders().add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN.toString(), ORIGIN_ALL); } else if (allowed == null || allowed.equals(ORIGIN_ALL) || allowed.contains(origin)) { -- cgit v1.2.3 From 4d59dd0973479bca3d51cf3bba6b0769a0d671c3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:47:56 -0700 Subject: Fix config injection --- src/main/java/org/traccar/MainModule.java | 16 +--------------- src/main/java/org/traccar/config/Config.java | 14 +++++++++++++- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 7dcc91f32..39d5a656a 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -22,7 +22,6 @@ import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Provides; import com.google.inject.Scopes; -import com.google.inject.name.Named; import com.google.inject.name.Names; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; @@ -61,7 +60,6 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; -import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; @@ -95,6 +93,7 @@ public class MainModule extends AbstractModule { @Override protected void configure() { bindConstant().annotatedWith(Names.named("configFile")).to(configFile); + bind(Config.class).asEagerSingleton(); bind(Storage.class).to(DatabaseStorage.class); bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); } @@ -111,19 +110,6 @@ public class MainModule extends AbstractModule { return objectMapper; } - @Singleton - @Provides - public static Config provideConfig(@Named("configFile") String configFile) throws Exception { - try { - Config config = new Config(configFile); - Log.setupLogger(config); - return config; - } catch (Exception e) { - Log.setupDefaultLogger(); - throw e; - } - } - @Provides public static Client provideClient() { return ClientBuilder.newClient().register( diff --git a/src/main/java/org/traccar/config/Config.java b/src/main/java/org/traccar/config/Config.java index 815a6e86a..5f95c16d9 100644 --- a/src/main/java/org/traccar/config/Config.java +++ b/src/main/java/org/traccar/config/Config.java @@ -16,13 +16,18 @@ package org.traccar.config; import com.google.common.annotations.VisibleForTesting; +import com.google.inject.name.Named; +import org.traccar.helper.Log; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.InvalidPropertiesFormatException; import java.util.Properties; +@Singleton public class Config { private final Properties properties = new Properties(); @@ -32,7 +37,8 @@ public class Config { public Config() { } - public Config(String file) throws IOException { + @Inject + public Config(@Named("configFile") String file) throws IOException { try { Properties mainProperties = new Properties(); try (InputStream inputStream = new FileInputStream(file)) { @@ -50,8 +56,14 @@ public class Config { useEnvironmentVariables = Boolean.parseBoolean(System.getenv("CONFIG_USE_ENVIRONMENT_VARIABLES")) || Boolean.parseBoolean(properties.getProperty("config.useEnvironmentVariables")); + + Log.setupLogger(this); } catch (InvalidPropertiesFormatException e) { + Log.setupDefaultLogger(); throw new RuntimeException("Configuration file is not a valid XML document", e); + } catch (Exception e) { + Log.setupDefaultLogger(); + throw e; } } -- cgit v1.2.3 From 8ed8f8051b735a6f7c9480601e27339dbe8dab01 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 13:52:08 -0700 Subject: Fix config defaults --- src/main/java/org/traccar/config/Keys.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6eb61607e..a03e47022 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -306,14 +306,16 @@ public final class Keys { */ public static final ConfigKey EVENT_FUEL_DROP_THRESHOLD = new DoubleConfigKey( "fuelDropThreshold", - List.of(KeyType.SERVER, KeyType.DEVICE)); + List.of(KeyType.SERVER, KeyType.DEVICE), + 0.0); /** * Speed limit value in knots. */ public static final ConfigKey EVENT_OVERSPEED_LIMIT = new DoubleConfigKey( "speedLimit", - List.of(KeyType.SERVER, KeyType.DEVICE)); + List.of(KeyType.SERVER, KeyType.DEVICE), + 0.0); /** * If true, the event is generated once at the beginning of overspeeding period. -- cgit v1.2.3 From ed64af90036d5e29b1e5fdf68df68c5c126beff7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 14:12:05 -0700 Subject: Fix geocoder injection --- src/main/java/org/traccar/MainModule.java | 56 +++++++++++++++------- src/main/java/org/traccar/geocoder/Geocoder.java | 4 ++ .../java/org/traccar/geocoder/JsonGeocoder.java | 13 +++-- 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 39d5a656a..3120118fc 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -146,7 +146,7 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static Geocoder provideGeocoder(Config config, Client client) { + public static Geocoder provideGeocoder(Config config, Client client, StatisticsManager statisticsManager) { if (config.getBoolean(Keys.GEOCODER_ENABLE)) { String type = config.getString(Keys.GEOCODER_TYPE, "google"); String url = config.getString(Keys.GEOCODER_URL); @@ -157,42 +157,62 @@ public class MainModule extends AbstractModule { AddressFormat addressFormat = formatString != null ? new AddressFormat(formatString) : new AddressFormat(); int cacheSize = config.getInteger(Keys.GEOCODER_CACHE_SIZE); + Geocoder geocoder; switch (type) { case "nominatim": - return new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); + geocoder = new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); + break; case "gisgraphy": - return new GisgraphyGeocoder(client, url, cacheSize, addressFormat); + geocoder = new GisgraphyGeocoder(client, url, cacheSize, addressFormat); + break; case "mapquest": - return new MapQuestGeocoder(client, url, key, cacheSize, addressFormat); + geocoder = new MapQuestGeocoder(client, url, key, cacheSize, addressFormat); + break; case "opencage": - return new OpenCageGeocoder(client, url, key, language, cacheSize, addressFormat); + geocoder = new OpenCageGeocoder(client, url, key, language, cacheSize, addressFormat); + break; case "bingmaps": - return new BingMapsGeocoder(client, url, key, cacheSize, addressFormat); + geocoder = new BingMapsGeocoder(client, url, key, cacheSize, addressFormat); + break; case "factual": - return new FactualGeocoder(client, url, key, cacheSize, addressFormat); + geocoder = new FactualGeocoder(client, url, key, cacheSize, addressFormat); + break; case "geocodefarm": - return new GeocodeFarmGeocoder(client, key, language, cacheSize, addressFormat); + geocoder = new GeocodeFarmGeocoder(client, key, language, cacheSize, addressFormat); + break; case "geocodexyz": - return new GeocodeXyzGeocoder(client, key, cacheSize, addressFormat); + geocoder = new GeocodeXyzGeocoder(client, key, cacheSize, addressFormat); + break; case "ban": - return new BanGeocoder(client, cacheSize, addressFormat); + geocoder = new BanGeocoder(client, cacheSize, addressFormat); + break; case "here": - return new HereGeocoder(client, url, id, key, language, cacheSize, addressFormat); + geocoder = new HereGeocoder(client, url, id, key, language, cacheSize, addressFormat); + break; case "mapmyindia": - return new MapmyIndiaGeocoder(client, url, key, cacheSize, addressFormat); + geocoder = new MapmyIndiaGeocoder(client, url, key, cacheSize, addressFormat); + break; case "tomtom": - return new TomTomGeocoder(client, url, key, cacheSize, addressFormat); + geocoder = new TomTomGeocoder(client, url, key, cacheSize, addressFormat); + break; case "positionstack": - return new PositionStackGeocoder(client, key, cacheSize, addressFormat); + geocoder = new PositionStackGeocoder(client, key, cacheSize, addressFormat); + break; case "mapbox": - return new MapboxGeocoder(client, key, cacheSize, addressFormat); + geocoder = new MapboxGeocoder(client, key, cacheSize, addressFormat); + break; case "maptiler": - return new MapTilerGeocoder(client, key, cacheSize, addressFormat); + geocoder = new MapTilerGeocoder(client, key, cacheSize, addressFormat); + break; case "geoapify": - return new GeoapifyGeocoder(client, key, language, cacheSize, addressFormat); + geocoder = new GeoapifyGeocoder(client, key, language, cacheSize, addressFormat); + break; default: - return new GoogleGeocoder(client, key, language, cacheSize, addressFormat); + geocoder = new GoogleGeocoder(client, key, language, cacheSize, addressFormat); + break; } + geocoder.setStatisticsManager(statisticsManager); + return geocoder; } return null; } diff --git a/src/main/java/org/traccar/geocoder/Geocoder.java b/src/main/java/org/traccar/geocoder/Geocoder.java index 587a27520..f4abe871a 100644 --- a/src/main/java/org/traccar/geocoder/Geocoder.java +++ b/src/main/java/org/traccar/geocoder/Geocoder.java @@ -15,6 +15,8 @@ */ package org.traccar.geocoder; +import org.traccar.database.StatisticsManager; + public interface Geocoder { interface ReverseGeocoderCallback { @@ -27,4 +29,6 @@ public interface Geocoder { String getAddress(double latitude, double longitude, ReverseGeocoderCallback callback); + void setStatisticsManager(StatisticsManager statisticsManager); + } diff --git a/src/main/java/org/traccar/geocoder/JsonGeocoder.java b/src/main/java/org/traccar/geocoder/JsonGeocoder.java index 0262de18c..6105e8cfd 100644 --- a/src/main/java/org/traccar/geocoder/JsonGeocoder.java +++ b/src/main/java/org/traccar/geocoder/JsonGeocoder.java @@ -17,7 +17,6 @@ package org.traccar.geocoder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; import org.traccar.database.StatisticsManager; import javax.json.JsonObject; @@ -36,6 +35,7 @@ public abstract class JsonGeocoder implements Geocoder { private final Client client; private final String url; private final AddressFormat addressFormat; + private StatisticsManager statisticsManager; private Map, String> cache; @@ -44,7 +44,7 @@ public abstract class JsonGeocoder implements Geocoder { this.url = url; this.addressFormat = addressFormat; if (cacheSize > 0) { - this.cache = Collections.synchronizedMap(new LinkedHashMap, String>() { + this.cache = Collections.synchronizedMap(new LinkedHashMap<>() { @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > cacheSize; @@ -53,6 +53,11 @@ public abstract class JsonGeocoder implements Geocoder { } } + @Override + public void setStatisticsManager(StatisticsManager statisticsManager) { + this.statisticsManager = statisticsManager; + } + protected String readValue(JsonObject object, String key) { if (object.containsKey(key) && !object.isNull(key)) { return object.getString(key); @@ -98,8 +103,8 @@ public abstract class JsonGeocoder implements Geocoder { } } - if (Main.getInjector() != null) { - Main.getInjector().getInstance(StatisticsManager.class).registerGeocoderRequest(); + if (statisticsManager != null) { + statisticsManager.registerGeocoderRequest(); } var request = client.target(String.format(url, latitude, longitude)).request(); -- cgit v1.2.3 From 367c6266918a9f21ec6a9eabd091b00016c1d1bf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 14:27:24 -0700 Subject: Inject all protocols --- src/main/java/org/traccar/ServerManager.java | 3 +-- src/main/java/org/traccar/TrackerClient.java | 4 +--- src/main/java/org/traccar/TrackerServer.java | 11 ++--------- src/main/java/org/traccar/protocol/AdmProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AisProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AlematicsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AnytrekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ApelProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AplicomProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AppelloProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AquilaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Ardi01Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ArknavProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ArknavX8Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ArmoliProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ArnaviProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AstraProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/At2000Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AtrackProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/AuroProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AustinNbProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AutoFonProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AutoGradeProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AutoTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/AvemaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Avl301Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/B2316Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/BceProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/BlackKiteProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/BlueProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/BoxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/C2stekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CalAmpProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CarTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CarcellProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CarscopProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CastelProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/CautelaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CellocatorProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/CguardProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CityeasyProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ContinentalProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/CradlepointProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DingtekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DishaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DmtHttpProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DmtProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DolphinProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Dsf22Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/DualcamProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/DwayProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EasyTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EelinkProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/EgtsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EnforaProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/EnnfuProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EnvotechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EsealProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/EskyProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/ExtremTracProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FifotrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FlespiProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FlexApiProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FlexCommProtocol.java | 7 +++++-- .../java/org/traccar/protocol/FlexibleReportProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FlextrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FoxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FreedomProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FreematicsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/FutureWayProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GalileoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GatorProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/GenxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gl100Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Gl200Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/GlobalSatProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GlobalstarProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GnxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GoSafeProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/GotopProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gps056Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gps103Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/GpsGateProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GpsMarkerProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GpsmtaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/GranitProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gs100Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gt02Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gt06Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Gt30Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/H02Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/HaicomProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/HomtecsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/HoopoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/HuaShengProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/HuabaoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/HunterProProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/IdplProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/IntellitracProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/IotmProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ItsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Ivt401Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/JidoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/JpKorjarProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Jt600Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/KenjiProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/KhdProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/L100Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/LacakProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/LaipacProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/LeafSpyProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/M2cProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/M2mProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MaestroProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ManPowerProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Mavlink2Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MegastekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MeiligaoProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/MeitrackProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/MictrackProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/MilesmateProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MiniFinderProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Minifinder2Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MobilogixProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MoovboxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MotorProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Mta6Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MtxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/MxtProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NavigilProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NavisProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NavisetProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NavtelecomProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NeosProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NetProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NiotProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NoranProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NvsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/NyitechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ObdDongleProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OigoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OkoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OmnicommProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OpenGtsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OrbcommProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OrionProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OsmAndProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OutsafeProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/OwnTracksProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PacificTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PathAwayProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PiligrimProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PluginProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PolteProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PortmanProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PretraceProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PricolProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/ProgressProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/PstProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Pt215Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Pt3000Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Pt502Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Pt60Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/R12wProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RadarProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RaveonProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RecodaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RetranslatorProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RitiProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RoboTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RstProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/RuptelaProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/S168Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SabertekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SanavProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/SanulProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SatsolProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SigfoxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SiwiProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SkypatrolProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SmartSoleProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SmokeyProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SolarPoweredProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SpotProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/StarLinkProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/StarcomProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/StartekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/StbProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Stl060Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SuntechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SupermateProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SviasProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/SwiftechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/T55Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/T57Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/T800xProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/TaipProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/TechTltProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TechtoCruzProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TelemaxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TelicProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TeltonikaProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/TeraTrackProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ThinkPowerProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/ThinkRaceProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Tk102Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Tk103Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Tlt2hProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TlvProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TmgProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TopflytechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TopinProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TotemProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Tr20Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Tr900Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/TrackboxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TrakMateProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TramigoProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TrvProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Tt8850Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TytanProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/TzoneProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/UlbotechProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/UproProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/UuxProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/V680Protocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/VisiontekProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/VnetProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Vt200Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/VtfmsProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/WatchProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/WialonProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/WliProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/WondexProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/WristbandProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Xexun2Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/XexunProtocol.java | 7 +++++-- src/main/java/org/traccar/protocol/XirgoProtocol.java | 9 ++++++--- src/main/java/org/traccar/protocol/Xrb28Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Xt013Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/Xt2400Protocol.java | 7 +++++-- src/main/java/org/traccar/protocol/YwtProtocol.java | 7 +++++-- 244 files changed, 1242 insertions(+), 529 deletions(-) diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 99fb9a494..8d6e615dc 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -46,8 +46,7 @@ public class ServerManager implements LifecycleObject { Injector injector, Config config) throws IOException, URISyntaxException, ReflectiveOperationException { for (Class protocolClass : ClassScanner.findSubclasses(BaseProtocol.class, "org.traccar.protocol")) { if (config.hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { - BaseProtocol protocol = (BaseProtocol) protocolClass.getDeclaredConstructor().newInstance(); - injector.injectMembers(protocol); + BaseProtocol protocol = (BaseProtocol) injector.getInstance(protocolClass); connectorList.addAll(protocol.getConnectorList()); protocolList.put(protocol.getName(), protocol); } diff --git a/src/main/java/org/traccar/TrackerClient.java b/src/main/java/org/traccar/TrackerClient.java index 2e8a73677..2d6b227da 100644 --- a/src/main/java/org/traccar/TrackerClient.java +++ b/src/main/java/org/traccar/TrackerClient.java @@ -53,9 +53,7 @@ public abstract class TrackerClient implements TrackerConnector { return secure; } - public TrackerClient(String protocol) { - Config config = Main.getInjector().getInstance(Config.class); - + public TrackerClient(Config config, String protocol) { secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); interval = config.getLong(Keys.PROTOCOL_INTERVAL.withPrefix(protocol)); address = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); diff --git a/src/main/java/org/traccar/TrackerServer.java b/src/main/java/org/traccar/TrackerServer.java index ccf3cd640..0e0837cfb 100644 --- a/src/main/java/org/traccar/TrackerServer.java +++ b/src/main/java/org/traccar/TrackerServer.java @@ -55,11 +55,7 @@ public abstract class TrackerServer implements TrackerConnector { return secure; } - public TrackerServer(boolean datagram, String protocol) { - this.datagram = datagram; - - Config config = Main.getInjector().getInstance(Config.class); - + public TrackerServer(Config config, String protocol, boolean datagram) { secure = config.getBoolean(Keys.PROTOCOL_SSL.withPrefix(protocol)); address = config.getString(Keys.PROTOCOL_ADDRESS.withPrefix(protocol)); port = config.getInteger(Keys.PROTOCOL_PORT.withPrefix(protocol)); @@ -83,20 +79,17 @@ public abstract class TrackerServer implements TrackerConnector { } }; + this.datagram = datagram; if (datagram) { - bootstrap = new Bootstrap() .group(EventLoopGroupFactory.getWorkerGroup()) .channel(NioDatagramChannel.class) .handler(pipelineFactory); - } else { - bootstrap = new ServerBootstrap() .group(EventLoopGroupFactory.getBossGroup(), EventLoopGroupFactory.getWorkerGroup()) .channel(NioServerSocketChannel.class) .childHandler(pipelineFactory); - } } diff --git a/src/main/java/org/traccar/protocol/AdmProtocol.java b/src/main/java/org/traccar/protocol/AdmProtocol.java index 8c5e2de0d..bab1d2339 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocol.java +++ b/src/main/java/org/traccar/protocol/AdmProtocol.java @@ -22,13 +22,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class AdmProtocol extends BaseProtocol { - public AdmProtocol() { + @Inject + public AdmProtocol(Config config) { setSupportedDataCommands( Command.TYPE_GET_DEVICE_STATUS, Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AdmFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/AisProtocol.java b/src/main/java/org/traccar/protocol/AisProtocol.java index 5697d7f3f..bc975c277 100644 --- a/src/main/java/org/traccar/protocol/AisProtocol.java +++ b/src/main/java/org/traccar/protocol/AisProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AisProtocol extends BaseProtocol { - public AisProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AisProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/AlematicsProtocol.java b/src/main/java/org/traccar/protocol/AlematicsProtocol.java index 1e68949ae..b85b44382 100644 --- a/src/main/java/org/traccar/protocol/AlematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/AlematicsProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AlematicsProtocol extends BaseProtocol { - public AlematicsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AlematicsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AlematicsFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/AnytrekProtocol.java b/src/main/java/org/traccar/protocol/AnytrekProtocol.java index 8c020e64e..b0e974c69 100644 --- a/src/main/java/org/traccar/protocol/AnytrekProtocol.java +++ b/src/main/java/org/traccar/protocol/AnytrekProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class AnytrekProtocol extends BaseProtocol { - public AnytrekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AnytrekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 2, 0, true)); diff --git a/src/main/java/org/traccar/protocol/ApelProtocol.java b/src/main/java/org/traccar/protocol/ApelProtocol.java index 0c0d6279e..f1d6e659c 100644 --- a/src/main/java/org/traccar/protocol/ApelProtocol.java +++ b/src/main/java/org/traccar/protocol/ApelProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class ApelProtocol extends BaseProtocol { - public ApelProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ApelProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); diff --git a/src/main/java/org/traccar/protocol/AplicomProtocol.java b/src/main/java/org/traccar/protocol/AplicomProtocol.java index 21556bd69..47bb780cb 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocol.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AplicomProtocol extends BaseProtocol { - public AplicomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AplicomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AplicomFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/AppelloProtocol.java b/src/main/java/org/traccar/protocol/AppelloProtocol.java index 919c8ab62..25b2bf3b8 100644 --- a/src/main/java/org/traccar/protocol/AppelloProtocol.java +++ b/src/main/java/org/traccar/protocol/AppelloProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AppelloProtocol extends BaseProtocol { - public AppelloProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AppelloProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/AquilaProtocol.java b/src/main/java/org/traccar/protocol/AquilaProtocol.java index 72161ccec..6080df33d 100644 --- a/src/main/java/org/traccar/protocol/AquilaProtocol.java +++ b/src/main/java/org/traccar/protocol/AquilaProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AquilaProtocol extends BaseProtocol { - public AquilaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AquilaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Ardi01Protocol.java b/src/main/java/org/traccar/protocol/Ardi01Protocol.java index ba9dc9dfa..b33c2817f 100644 --- a/src/main/java/org/traccar/protocol/Ardi01Protocol.java +++ b/src/main/java/org/traccar/protocol/Ardi01Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Ardi01Protocol extends BaseProtocol { - public Ardi01Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Ardi01Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/ArknavProtocol.java b/src/main/java/org/traccar/protocol/ArknavProtocol.java index 76db3781c..ed38f26d7 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocol.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ArknavProtocol extends BaseProtocol { - public ArknavProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArknavProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); diff --git a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java index 55d2c58f9..39c6e8009 100644 --- a/src/main/java/org/traccar/protocol/ArknavX8Protocol.java +++ b/src/main/java/org/traccar/protocol/ArknavX8Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ArknavX8Protocol extends BaseProtocol { - public ArknavX8Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArknavX8Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); diff --git a/src/main/java/org/traccar/protocol/ArmoliProtocol.java b/src/main/java/org/traccar/protocol/ArmoliProtocol.java index 70e70c89b..32fba3b52 100644 --- a/src/main/java/org/traccar/protocol/ArmoliProtocol.java +++ b/src/main/java/org/traccar/protocol/ArmoliProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ArmoliProtocol extends BaseProtocol { - public ArmoliProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArmoliProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";;", ";\r", ";")); diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocol.java b/src/main/java/org/traccar/protocol/ArnaviProtocol.java index 18af4e9be..091d5c06f 100644 --- a/src/main/java/org/traccar/protocol/ArnaviProtocol.java +++ b/src/main/java/org/traccar/protocol/ArnaviProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ArnaviProtocol extends BaseProtocol { - public ArnaviProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ArnaviProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new ArnaviFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/AstraProtocol.java b/src/main/java/org/traccar/protocol/AstraProtocol.java index c79c7f6fc..021a81e07 100644 --- a/src/main/java/org/traccar/protocol/AstraProtocol.java +++ b/src/main/java/org/traccar/protocol/AstraProtocol.java @@ -21,17 +21,20 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AstraProtocol extends BaseProtocol { - public AstraProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AstraProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -3, 0)); pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AstraProtocolDecoder(AstraProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/At2000Protocol.java b/src/main/java/org/traccar/protocol/At2000Protocol.java index 44bb11b94..25e9be86f 100644 --- a/src/main/java/org/traccar/protocol/At2000Protocol.java +++ b/src/main/java/org/traccar/protocol/At2000Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class At2000Protocol extends BaseProtocol { - public At2000Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public At2000Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new At2000FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/AtrackProtocol.java b/src/main/java/org/traccar/protocol/AtrackProtocol.java index 65cd5194e..21eb09696 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class AtrackProtocol extends BaseProtocol { - public AtrackProtocol() { + @Inject + public AtrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AtrackFrameDecoder()); @@ -34,7 +37,7 @@ public class AtrackProtocol extends BaseProtocol { pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/AuroProtocol.java b/src/main/java/org/traccar/protocol/AuroProtocol.java index f05b3f71c..d37884c8b 100644 --- a/src/main/java/org/traccar/protocol/AuroProtocol.java +++ b/src/main/java/org/traccar/protocol/AuroProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AuroProtocol extends BaseProtocol { - public AuroProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AuroProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocol.java b/src/main/java/org/traccar/protocol/AustinNbProtocol.java index 18a1c6c6a..6a68467e2 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocol.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AustinNbProtocol extends BaseProtocol { - public AustinNbProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public AustinNbProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/AutoFonProtocol.java b/src/main/java/org/traccar/protocol/AutoFonProtocol.java index 36d384c94..0566b1da6 100644 --- a/src/main/java/org/traccar/protocol/AutoFonProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoFonProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AutoFonProtocol extends BaseProtocol { - public AutoFonProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AutoFonProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new AutoFonFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java index c9d997163..bc80e473a 100644 --- a/src/main/java/org/traccar/protocol/AutoGradeProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoGradeProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AutoGradeProtocol extends BaseProtocol { - public AutoGradeProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AutoGradeProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java index 99a59fad7..80255d3e9 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class AutoTrackProtocol extends BaseProtocol { - public AutoTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AutoTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 5, 2, 2, 0, true)); diff --git a/src/main/java/org/traccar/protocol/AvemaProtocol.java b/src/main/java/org/traccar/protocol/AvemaProtocol.java index 69d2cbfa7..b35a447ff 100644 --- a/src/main/java/org/traccar/protocol/AvemaProtocol.java +++ b/src/main/java/org/traccar/protocol/AvemaProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class AvemaProtocol extends BaseProtocol { - public AvemaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public AvemaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Avl301Protocol.java b/src/main/java/org/traccar/protocol/Avl301Protocol.java index bae4de7d0..c4a0affdc 100644 --- a/src/main/java/org/traccar/protocol/Avl301Protocol.java +++ b/src/main/java/org/traccar/protocol/Avl301Protocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Avl301Protocol extends BaseProtocol { - public Avl301Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Avl301Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, -3, 0)); diff --git a/src/main/java/org/traccar/protocol/B2316Protocol.java b/src/main/java/org/traccar/protocol/B2316Protocol.java index 5b9d297f9..582be0b56 100644 --- a/src/main/java/org/traccar/protocol/B2316Protocol.java +++ b/src/main/java/org/traccar/protocol/B2316Protocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class B2316Protocol extends BaseProtocol { - public B2316Protocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public B2316Protocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/BceProtocol.java b/src/main/java/org/traccar/protocol/BceProtocol.java index 2d92894aa..31fb1bd83 100644 --- a/src/main/java/org/traccar/protocol/BceProtocol.java +++ b/src/main/java/org/traccar/protocol/BceProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class BceProtocol extends BaseProtocol { - public BceProtocol() { + @Inject + public BceProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new BceFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java index e464b18d1..3859a9273 100644 --- a/src/main/java/org/traccar/protocol/BlackKiteProtocol.java +++ b/src/main/java/org/traccar/protocol/BlackKiteProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class BlackKiteProtocol extends BaseProtocol { - public BlackKiteProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public BlackKiteProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GalileoFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/BlueProtocol.java b/src/main/java/org/traccar/protocol/BlueProtocol.java index 9d42e386e..da195f438 100644 --- a/src/main/java/org/traccar/protocol/BlueProtocol.java +++ b/src/main/java/org/traccar/protocol/BlueProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class BlueProtocol extends BaseProtocol { - public BlueProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public BlueProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -2, 0)); diff --git a/src/main/java/org/traccar/protocol/BoxProtocol.java b/src/main/java/org/traccar/protocol/BoxProtocol.java index 72a13c94a..dc6852d50 100644 --- a/src/main/java/org/traccar/protocol/BoxProtocol.java +++ b/src/main/java/org/traccar/protocol/BoxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class BoxProtocol extends BaseProtocol { - public BoxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public BoxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); diff --git a/src/main/java/org/traccar/protocol/C2stekProtocol.java b/src/main/java/org/traccar/protocol/C2stekProtocol.java index da490aedc..5cd8ef4fd 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocol.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class C2stekProtocol extends BaseProtocol { - public C2stekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public C2stekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, false, "$AP")); diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocol.java b/src/main/java/org/traccar/protocol/CalAmpProtocol.java index 056f23d01..d67308cf2 100644 --- a/src/main/java/org/traccar/protocol/CalAmpProtocol.java +++ b/src/main/java/org/traccar/protocol/CalAmpProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CalAmpProtocol extends BaseProtocol { - public CalAmpProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public CalAmpProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CalAmpProtocolDecoder(CalAmpProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/CarTrackProtocol.java b/src/main/java/org/traccar/protocol/CarTrackProtocol.java index 133fd8036..0538aad72 100644 --- a/src/main/java/org/traccar/protocol/CarTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/CarTrackProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CarTrackProtocol extends BaseProtocol { - public CarTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CarTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); diff --git a/src/main/java/org/traccar/protocol/CarcellProtocol.java b/src/main/java/org/traccar/protocol/CarcellProtocol.java index 489b1d1de..832d9bb2d 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocol.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocol.java @@ -24,13 +24,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class CarcellProtocol extends BaseProtocol { - public CarcellProtocol() { + @Inject + public CarcellProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r')); diff --git a/src/main/java/org/traccar/protocol/CarscopProtocol.java b/src/main/java/org/traccar/protocol/CarscopProtocol.java index d4c246c59..a4413af28 100644 --- a/src/main/java/org/traccar/protocol/CarscopProtocol.java +++ b/src/main/java/org/traccar/protocol/CarscopProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CarscopProtocol extends BaseProtocol { - public CarscopProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CarscopProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '^')); diff --git a/src/main/java/org/traccar/protocol/CastelProtocol.java b/src/main/java/org/traccar/protocol/CastelProtocol.java index ee5432753..9323b1503 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocol.java +++ b/src/main/java/org/traccar/protocol/CastelProtocol.java @@ -23,13 +23,16 @@ import org.traccar.config.Config; import org.traccar.model.Command; import java.nio.ByteOrder; +import javax.inject.Inject; + public class CastelProtocol extends BaseProtocol { - public CastelProtocol() { + @Inject + public CastelProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); @@ -37,7 +40,7 @@ public class CastelProtocol extends BaseProtocol { pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/CautelaProtocol.java b/src/main/java/org/traccar/protocol/CautelaProtocol.java index 13f3770b7..d0ca35ef1 100644 --- a/src/main/java/org/traccar/protocol/CautelaProtocol.java +++ b/src/main/java/org/traccar/protocol/CautelaProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CautelaProtocol extends BaseProtocol { - public CautelaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CautelaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocol.java b/src/main/java/org/traccar/protocol/CellocatorProtocol.java index 6532848ac..3287928c7 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocol.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class CellocatorProtocol extends BaseProtocol { - public CellocatorProtocol() { + @Inject + public CellocatorProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CellocatorFrameDecoder()); @@ -34,7 +37,7 @@ public class CellocatorProtocol extends BaseProtocol { pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/CguardProtocol.java b/src/main/java/org/traccar/protocol/CguardProtocol.java index ad5539fbd..caf0aad42 100644 --- a/src/main/java/org/traccar/protocol/CguardProtocol.java +++ b/src/main/java/org/traccar/protocol/CguardProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CguardProtocol extends BaseProtocol { - public CguardProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CguardProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocol.java b/src/main/java/org/traccar/protocol/CityeasyProtocol.java index 28337bde9..9656b284b 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocol.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocol.java @@ -22,15 +22,18 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class CityeasyProtocol extends BaseProtocol { - public CityeasyProtocol() { + @Inject + public CityeasyProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_POSITION_STOP, Command.TYPE_SET_TIMEZONE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); diff --git a/src/main/java/org/traccar/protocol/ContinentalProtocol.java b/src/main/java/org/traccar/protocol/ContinentalProtocol.java index bbff3bda6..06e93d79d 100644 --- a/src/main/java/org/traccar/protocol/ContinentalProtocol.java +++ b/src/main/java/org/traccar/protocol/ContinentalProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ContinentalProtocol extends BaseProtocol { - public ContinentalProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ContinentalProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); diff --git a/src/main/java/org/traccar/protocol/CradlepointProtocol.java b/src/main/java/org/traccar/protocol/CradlepointProtocol.java index 7d2270743..7f201a31d 100644 --- a/src/main/java/org/traccar/protocol/CradlepointProtocol.java +++ b/src/main/java/org/traccar/protocol/CradlepointProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class CradlepointProtocol extends BaseProtocol { - public CradlepointProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public CradlepointProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/DingtekProtocol.java b/src/main/java/org/traccar/protocol/DingtekProtocol.java index 7864d24df..e9466b7e8 100644 --- a/src/main/java/org/traccar/protocol/DingtekProtocol.java +++ b/src/main/java/org/traccar/protocol/DingtekProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class DingtekProtocol extends BaseProtocol { - public DingtekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DingtekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new DingtekFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/DishaProtocol.java b/src/main/java/org/traccar/protocol/DishaProtocol.java index c81c88c7c..f83b8349a 100644 --- a/src/main/java/org/traccar/protocol/DishaProtocol.java +++ b/src/main/java/org/traccar/protocol/DishaProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class DishaProtocol extends BaseProtocol { - public DishaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DishaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java index 107ec430c..0dab26cda 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class DmtHttpProtocol extends BaseProtocol { - public DmtHttpProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DmtHttpProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/DmtProtocol.java b/src/main/java/org/traccar/protocol/DmtProtocol.java index d84099fac..de56c9372 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocol.java +++ b/src/main/java/org/traccar/protocol/DmtProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class DmtProtocol extends BaseProtocol { - public DmtProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DmtProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); diff --git a/src/main/java/org/traccar/protocol/DolphinProtocol.java b/src/main/java/org/traccar/protocol/DolphinProtocol.java index 1e67de8b2..ed627be78 100644 --- a/src/main/java/org/traccar/protocol/DolphinProtocol.java +++ b/src/main/java/org/traccar/protocol/DolphinProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class DolphinProtocol extends BaseProtocol { - public DolphinProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DolphinProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 4096, 20, 4, 4, 0, true)); diff --git a/src/main/java/org/traccar/protocol/Dsf22Protocol.java b/src/main/java/org/traccar/protocol/Dsf22Protocol.java index fcc7e7d55..06c99b0f9 100644 --- a/src/main/java/org/traccar/protocol/Dsf22Protocol.java +++ b/src/main/java/org/traccar/protocol/Dsf22Protocol.java @@ -20,17 +20,20 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Dsf22Protocol extends BaseProtocol { - public Dsf22Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Dsf22Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Dsf22FrameDecoder()); pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Dsf22ProtocolDecoder(Dsf22Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/DualcamProtocol.java b/src/main/java/org/traccar/protocol/DualcamProtocol.java index ba1dc0e4b..363a2c5d9 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocol.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class DualcamProtocol extends BaseProtocol { - public DualcamProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DualcamProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new DualcamFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/DwayProtocol.java b/src/main/java/org/traccar/protocol/DwayProtocol.java index a729d6401..1096c945c 100644 --- a/src/main/java/org/traccar/protocol/DwayProtocol.java +++ b/src/main/java/org/traccar/protocol/DwayProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class DwayProtocol extends BaseProtocol { - public DwayProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public DwayProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java index 0c1fec7e8..39aa61580 100644 --- a/src/main/java/org/traccar/protocol/EasyTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/EasyTrackProtocol.java @@ -24,15 +24,18 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EasyTrackProtocol extends BaseProtocol { - public EasyTrackProtocol() { + @Inject + public EasyTrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#\r\n", "#", "\r\n")); diff --git a/src/main/java/org/traccar/protocol/EelinkProtocol.java b/src/main/java/org/traccar/protocol/EelinkProtocol.java index 654468ea0..35fd4fe65 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocol.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocol.java @@ -22,16 +22,19 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EelinkProtocol extends BaseProtocol { - public EelinkProtocol() { + @Inject + public EelinkProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); @@ -39,7 +42,7 @@ public class EelinkProtocol extends BaseProtocol { pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, true)); diff --git a/src/main/java/org/traccar/protocol/EgtsProtocol.java b/src/main/java/org/traccar/protocol/EgtsProtocol.java index fb17e41ae..f257271d4 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocol.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class EgtsProtocol extends BaseProtocol { - public EgtsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EgtsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EgtsFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/EnforaProtocol.java b/src/main/java/org/traccar/protocol/EnforaProtocol.java index 5386787ea..ebde56f70 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocol.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocol.java @@ -22,14 +22,17 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EnforaProtocol extends BaseProtocol { - public EnforaProtocol() { + @Inject + public EnforaProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, -2, 2)); @@ -37,7 +40,7 @@ public class EnforaProtocol extends BaseProtocol { pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/EnnfuProtocol.java b/src/main/java/org/traccar/protocol/EnnfuProtocol.java index e72ff29ba..e326481fa 100644 --- a/src/main/java/org/traccar/protocol/EnnfuProtocol.java +++ b/src/main/java/org/traccar/protocol/EnnfuProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class EnnfuProtocol extends BaseProtocol { - public EnnfuProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EnnfuProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocol.java b/src/main/java/org/traccar/protocol/EnvotechProtocol.java index 8ccf1776f..dffa1c991 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocol.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class EnvotechProtocol extends BaseProtocol { - public EnvotechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EnvotechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/EsealProtocol.java b/src/main/java/org/traccar/protocol/EsealProtocol.java index e63e7ee5f..0ed80dc6f 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocol.java +++ b/src/main/java/org/traccar/protocol/EsealProtocol.java @@ -24,14 +24,17 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class EsealProtocol extends BaseProtocol { - public EsealProtocol() { + @Inject + public EsealProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/EskyProtocol.java b/src/main/java/org/traccar/protocol/EskyProtocol.java index dd81f4954..cb2f59dc8 100644 --- a/src/main/java/org/traccar/protocol/EskyProtocol.java +++ b/src/main/java/org/traccar/protocol/EskyProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class EskyProtocol extends BaseProtocol { - public EskyProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public EskyProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new EskyFrameDecoder()); @@ -34,7 +37,7 @@ public class EskyProtocol extends BaseProtocol { pipeline.addLast(new EskyProtocolDecoder(EskyProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java index 4da56a8eb..ffc941b69 100644 --- a/src/main/java/org/traccar/protocol/ExtremTracProtocol.java +++ b/src/main/java/org/traccar/protocol/ExtremTracProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ExtremTracProtocol extends BaseProtocol { - public ExtremTracProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ExtremTracProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocol.java b/src/main/java/org/traccar/protocol/FifotrackProtocol.java index 7de8f3f62..fd2beaabb 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocol.java @@ -22,13 +22,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class FifotrackProtocol extends BaseProtocol { - public FifotrackProtocol() { + @Inject + public FifotrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FifotrackFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/FlespiProtocol.java b/src/main/java/org/traccar/protocol/FlespiProtocol.java index 874be7f68..374cf77e2 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FlespiProtocol extends BaseProtocol { - public FlespiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlespiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocol.java b/src/main/java/org/traccar/protocol/FlexApiProtocol.java index 87ae8e274..088072d2d 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocol.java @@ -24,10 +24,13 @@ import org.traccar.config.Config; import java.nio.charset.StandardCharsets; +import javax.inject.Inject; + public class FlexApiProtocol extends BaseProtocol { - public FlexApiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlexApiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(5120)); diff --git a/src/main/java/org/traccar/protocol/FlexCommProtocol.java b/src/main/java/org/traccar/protocol/FlexCommProtocol.java index 6e6e59f24..5397156cb 100644 --- a/src/main/java/org/traccar/protocol/FlexCommProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexCommProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FlexCommProtocol extends BaseProtocol { - public FlexCommProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlexCommProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(2 + 2 + 101 + 5)); diff --git a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java index 0d6437d83..61e315af9 100644 --- a/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java +++ b/src/main/java/org/traccar/protocol/FlexibleReportProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FlexibleReportProtocol extends BaseProtocol { - public FlexibleReportProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public FlexibleReportProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FlexibleReportProtocolDecoder(FlexibleReportProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/FlextrackProtocol.java b/src/main/java/org/traccar/protocol/FlextrackProtocol.java index f80460477..ebac8b4de 100644 --- a/src/main/java/org/traccar/protocol/FlextrackProtocol.java +++ b/src/main/java/org/traccar/protocol/FlextrackProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FlextrackProtocol extends BaseProtocol { - public FlextrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FlextrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); diff --git a/src/main/java/org/traccar/protocol/FoxProtocol.java b/src/main/java/org/traccar/protocol/FoxProtocol.java index a91c2b2c5..fa45b3817 100644 --- a/src/main/java/org/traccar/protocol/FoxProtocol.java +++ b/src/main/java/org/traccar/protocol/FoxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FoxProtocol extends BaseProtocol { - public FoxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FoxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "")); diff --git a/src/main/java/org/traccar/protocol/FreedomProtocol.java b/src/main/java/org/traccar/protocol/FreedomProtocol.java index 6a7a2d72e..dac117c04 100644 --- a/src/main/java/org/traccar/protocol/FreedomProtocol.java +++ b/src/main/java/org/traccar/protocol/FreedomProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FreedomProtocol extends BaseProtocol { - public FreedomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FreedomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocol.java b/src/main/java/org/traccar/protocol/FreematicsProtocol.java index 0220b2030..dce4994ab 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocol.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FreematicsProtocol extends BaseProtocol { - public FreematicsProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public FreematicsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/FutureWayProtocol.java b/src/main/java/org/traccar/protocol/FutureWayProtocol.java index 7d2160345..715dd3c9c 100644 --- a/src/main/java/org/traccar/protocol/FutureWayProtocol.java +++ b/src/main/java/org/traccar/protocol/FutureWayProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class FutureWayProtocol extends BaseProtocol { - public FutureWayProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public FutureWayProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FutureWayFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/GalileoProtocol.java b/src/main/java/org/traccar/protocol/GalileoProtocol.java index a3cda7fa1..90e95574a 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocol.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocol.java @@ -21,13 +21,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class GalileoProtocol extends BaseProtocol { - public GalileoProtocol() { + @Inject + public GalileoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GalileoFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/GatorProtocol.java b/src/main/java/org/traccar/protocol/GatorProtocol.java index a123b36ec..7341b69a3 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocol.java +++ b/src/main/java/org/traccar/protocol/GatorProtocol.java @@ -21,17 +21,20 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GatorProtocol extends BaseProtocol { - public GatorProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GatorProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GatorProtocolDecoder(GatorProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/GenxProtocol.java b/src/main/java/org/traccar/protocol/GenxProtocol.java index 5bd89c512..97d8633a0 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocol.java +++ b/src/main/java/org/traccar/protocol/GenxProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GenxProtocol extends BaseProtocol { - public GenxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GenxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Gl100Protocol.java b/src/main/java/org/traccar/protocol/Gl100Protocol.java index 91b039467..e1748c9a0 100644 --- a/src/main/java/org/traccar/protocol/Gl100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl100Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Gl100Protocol extends BaseProtocol { - public Gl100Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gl100Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); @@ -35,7 +38,7 @@ public class Gl100Protocol extends BaseProtocol { pipeline.addLast(new Gl100ProtocolDecoder(Gl100Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Gl200Protocol.java b/src/main/java/org/traccar/protocol/Gl200Protocol.java index 4d74e3116..c7b6a8e7c 100644 --- a/src/main/java/org/traccar/protocol/Gl200Protocol.java +++ b/src/main/java/org/traccar/protocol/Gl200Protocol.java @@ -22,16 +22,19 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Gl200Protocol extends BaseProtocol { - public Gl200Protocol() { + @Inject + public Gl200Protocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_IDENTIFICATION, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gl200FrameDecoder()); @@ -40,7 +43,7 @@ public class Gl200Protocol extends BaseProtocol { pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java index d5e3a483b..16b99f426 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocol.java @@ -24,14 +24,17 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class GlobalSatProtocol extends BaseProtocol { - public GlobalSatProtocol() { + @Inject + public GlobalSatProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ALARM_DISMISS, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "!\r\n", "!")); diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java index e829ff37e..293f5fda5 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocol.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GlobalstarProtocol extends BaseProtocol { - public GlobalstarProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GlobalstarProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/GnxProtocol.java b/src/main/java/org/traccar/protocol/GnxProtocol.java index c51888336..32d642688 100644 --- a/src/main/java/org/traccar/protocol/GnxProtocol.java +++ b/src/main/java/org/traccar/protocol/GnxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GnxProtocol extends BaseProtocol { - public GnxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GnxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\n\r")); diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocol.java b/src/main/java/org/traccar/protocol/GoSafeProtocol.java index 35216436a..607931500 100644 --- a/src/main/java/org/traccar/protocol/GoSafeProtocol.java +++ b/src/main/java/org/traccar/protocol/GoSafeProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GoSafeProtocol extends BaseProtocol { - public GoSafeProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GoSafeProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); @@ -35,7 +38,7 @@ public class GoSafeProtocol extends BaseProtocol { pipeline.addLast(new GoSafeProtocolDecoder(GoSafeProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GotopProtocol.java b/src/main/java/org/traccar/protocol/GotopProtocol.java index e2fe4ff93..53fcea0d0 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocol.java +++ b/src/main/java/org/traccar/protocol/GotopProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GotopProtocol extends BaseProtocol { - public GotopProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GotopProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/Gps056Protocol.java b/src/main/java/org/traccar/protocol/Gps056Protocol.java index fa7e5c12e..dbffbfdbb 100644 --- a/src/main/java/org/traccar/protocol/Gps056Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps056Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Gps056Protocol extends BaseProtocol { - public Gps056Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gps056Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gps056FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Gps103Protocol.java b/src/main/java/org/traccar/protocol/Gps103Protocol.java index bf0b01526..2725494c5 100644 --- a/src/main/java/org/traccar/protocol/Gps103Protocol.java +++ b/src/main/java/org/traccar/protocol/Gps103Protocol.java @@ -24,9 +24,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Gps103Protocol extends BaseProtocol { - public Gps103Protocol() { + @Inject + public Gps103Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, @@ -37,7 +40,7 @@ public class Gps103Protocol extends BaseProtocol { Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(2048, false, "\r\n", "\n", ";", "*")); @@ -47,7 +50,7 @@ public class Gps103Protocol extends BaseProtocol { pipeline.addLast(new Gps103ProtocolDecoder(Gps103Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GpsGateProtocol.java b/src/main/java/org/traccar/protocol/GpsGateProtocol.java index 51dbae7e3..a6a73ae6b 100644 --- a/src/main/java/org/traccar/protocol/GpsGateProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsGateProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GpsGateProtocol extends BaseProtocol { - public GpsGateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GpsGateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\0", "\n", "\r\n")); diff --git a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java index 3a0c1aeb9..12b53342c 100644 --- a/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsMarkerProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GpsMarkerProtocol extends BaseProtocol { - public GpsMarkerProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public GpsMarkerProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); diff --git a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java index 68241958b..a474b1e53 100644 --- a/src/main/java/org/traccar/protocol/GpsmtaProtocol.java +++ b/src/main/java/org/traccar/protocol/GpsmtaProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class GpsmtaProtocol extends BaseProtocol { - public GpsmtaProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public GpsmtaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/GranitProtocol.java b/src/main/java/org/traccar/protocol/GranitProtocol.java index 58c3d1ba4..bb66501e2 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocol.java +++ b/src/main/java/org/traccar/protocol/GranitProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class GranitProtocol extends BaseProtocol { - public GranitProtocol() { + @Inject + public GranitProtocol(Config config) { setSupportedDataCommands( Command.TYPE_IDENTIFICATION, Command.TYPE_REBOOT_DEVICE, @@ -33,7 +36,7 @@ public class GranitProtocol extends BaseProtocol { setSupportedTextCommands( Command.TYPE_REBOOT_DEVICE, Command.TYPE_POSITION_PERIODIC); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new GranitFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Gs100Protocol.java b/src/main/java/org/traccar/protocol/Gs100Protocol.java index bd7c21b57..425ca9330 100644 --- a/src/main/java/org/traccar/protocol/Gs100Protocol.java +++ b/src/main/java/org/traccar/protocol/Gs100Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Gs100Protocol extends BaseProtocol { - public Gs100Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gs100Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gs100ProtocolDecoder(Gs100Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Gt02Protocol.java b/src/main/java/org/traccar/protocol/Gt02Protocol.java index c57de2fd6..fa05761f6 100644 --- a/src/main/java/org/traccar/protocol/Gt02Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt02Protocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Gt02Protocol extends BaseProtocol { - public Gt02Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gt02Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 1, 2, 0)); diff --git a/src/main/java/org/traccar/protocol/Gt06Protocol.java b/src/main/java/org/traccar/protocol/Gt06Protocol.java index 48eb77c0c..38278121c 100644 --- a/src/main/java/org/traccar/protocol/Gt06Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt06Protocol.java @@ -21,14 +21,17 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Gt06Protocol extends BaseProtocol { - public Gt06Protocol() { + @Inject + public Gt06Protocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Gt06FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Gt30Protocol.java b/src/main/java/org/traccar/protocol/Gt30Protocol.java index da401acd1..6b79ba58b 100644 --- a/src/main/java/org/traccar/protocol/Gt30Protocol.java +++ b/src/main/java/org/traccar/protocol/Gt30Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Gt30Protocol extends BaseProtocol { - public Gt30Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Gt30Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/H02Protocol.java b/src/main/java/org/traccar/protocol/H02Protocol.java index d35333171..4e5f8c96a 100644 --- a/src/main/java/org/traccar/protocol/H02Protocol.java +++ b/src/main/java/org/traccar/protocol/H02Protocol.java @@ -23,9 +23,12 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; +import javax.inject.Inject; + public class H02Protocol extends BaseProtocol { - public H02Protocol() { + @Inject + public H02Protocol(Config config) { setSupportedDataCommands( Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, @@ -33,7 +36,7 @@ public class H02Protocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME, Command.TYPE_POSITION_PERIODIC ); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { int messageLength = config.getInteger(Keys.PROTOCOL_MESSAGE_LENGTH.withPrefix(getName())); @@ -43,7 +46,7 @@ public class H02Protocol extends BaseProtocol { pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/HaicomProtocol.java b/src/main/java/org/traccar/protocol/HaicomProtocol.java index c03c3c0b3..f56c605f0 100644 --- a/src/main/java/org/traccar/protocol/HaicomProtocol.java +++ b/src/main/java/org/traccar/protocol/HaicomProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class HaicomProtocol extends BaseProtocol { - public HaicomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HaicomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '*')); diff --git a/src/main/java/org/traccar/protocol/HomtecsProtocol.java b/src/main/java/org/traccar/protocol/HomtecsProtocol.java index 85e4012a2..aa2d7d852 100644 --- a/src/main/java/org/traccar/protocol/HomtecsProtocol.java +++ b/src/main/java/org/traccar/protocol/HomtecsProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class HomtecsProtocol extends BaseProtocol { - public HomtecsProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public HomtecsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/HoopoProtocol.java b/src/main/java/org/traccar/protocol/HoopoProtocol.java index 8795ed727..02d8e5a8e 100644 --- a/src/main/java/org/traccar/protocol/HoopoProtocol.java +++ b/src/main/java/org/traccar/protocol/HoopoProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class HoopoProtocol extends BaseProtocol { - public HoopoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HoopoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocol.java b/src/main/java/org/traccar/protocol/HuaShengProtocol.java index bf3b2052a..b1b61e977 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocol.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class HuaShengProtocol extends BaseProtocol { - public HuaShengProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HuaShengProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuaShengFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocol.java b/src/main/java/org/traccar/protocol/HuabaoProtocol.java index 0e1ab0b02..c37918b0e 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocol.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocol.java @@ -21,13 +21,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class HuabaoProtocol extends BaseProtocol { - public HuabaoProtocol() { + @Inject + public HuabaoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuabaoFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/HunterProProtocol.java b/src/main/java/org/traccar/protocol/HunterProProtocol.java index e0f8bab28..ed4289d73 100644 --- a/src/main/java/org/traccar/protocol/HunterProProtocol.java +++ b/src/main/java/org/traccar/protocol/HunterProProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class HunterProProtocol extends BaseProtocol { - public HunterProProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public HunterProProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "\r")); diff --git a/src/main/java/org/traccar/protocol/IdplProtocol.java b/src/main/java/org/traccar/protocol/IdplProtocol.java index 5dda72c64..aa1f4ff5b 100644 --- a/src/main/java/org/traccar/protocol/IdplProtocol.java +++ b/src/main/java/org/traccar/protocol/IdplProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class IdplProtocol extends BaseProtocol { - public IdplProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public IdplProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/IntellitracProtocol.java b/src/main/java/org/traccar/protocol/IntellitracProtocol.java index c39be0fd0..b1a91cca9 100644 --- a/src/main/java/org/traccar/protocol/IntellitracProtocol.java +++ b/src/main/java/org/traccar/protocol/IntellitracProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class IntellitracProtocol extends BaseProtocol { - public IntellitracProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public IntellitracProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new IntellitracFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/IotmProtocol.java b/src/main/java/org/traccar/protocol/IotmProtocol.java index b59d0ff3d..0d288f4bf 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocol.java +++ b/src/main/java/org/traccar/protocol/IotmProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class IotmProtocol extends BaseProtocol { - public IotmProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public IotmProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(MqttEncoder.INSTANCE); diff --git a/src/main/java/org/traccar/protocol/ItsProtocol.java b/src/main/java/org/traccar/protocol/ItsProtocol.java index 76097b20f..5148e8ab0 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocol.java +++ b/src/main/java/org/traccar/protocol/ItsProtocol.java @@ -23,13 +23,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class ItsProtocol extends BaseProtocol { - public ItsProtocol() { + @Inject + public ItsProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new ItsFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Ivt401Protocol.java b/src/main/java/org/traccar/protocol/Ivt401Protocol.java index 2ef3ea2bf..763457641 100644 --- a/src/main/java/org/traccar/protocol/Ivt401Protocol.java +++ b/src/main/java/org/traccar/protocol/Ivt401Protocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Ivt401Protocol extends BaseProtocol { - public Ivt401Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Ivt401Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); diff --git a/src/main/java/org/traccar/protocol/JidoProtocol.java b/src/main/java/org/traccar/protocol/JidoProtocol.java index 1040b45b9..78aa6c81c 100644 --- a/src/main/java/org/traccar/protocol/JidoProtocol.java +++ b/src/main/java/org/traccar/protocol/JidoProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class JidoProtocol extends BaseProtocol { - public JidoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public JidoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java index c27dde8f1..30c8e9977 100644 --- a/src/main/java/org/traccar/protocol/JpKorjarProtocol.java +++ b/src/main/java/org/traccar/protocol/JpKorjarProtocol.java @@ -1,6 +1,6 @@ /* + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 Nyash (nyashh@gmail.com) - * Copyright 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class JpKorjarProtocol extends BaseProtocol { - public JpKorjarProtocol() { - addServer(new TrackerServer(false, this.getName()) { + @Inject + public JpKorjarProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JpKorjarFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Jt600Protocol.java b/src/main/java/org/traccar/protocol/Jt600Protocol.java index 7bc88de21..bf0b3379e 100644 --- a/src/main/java/org/traccar/protocol/Jt600Protocol.java +++ b/src/main/java/org/traccar/protocol/Jt600Protocol.java @@ -22,15 +22,18 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Jt600Protocol extends BaseProtocol { - public Jt600Protocol() { + @Inject + public Jt600Protocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_RESUME, Command.TYPE_ENGINE_STOP, Command.TYPE_SET_TIMEZONE, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Jt600FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/KenjiProtocol.java b/src/main/java/org/traccar/protocol/KenjiProtocol.java index 91d5cf5b6..8d78c8c56 100644 --- a/src/main/java/org/traccar/protocol/KenjiProtocol.java +++ b/src/main/java/org/traccar/protocol/KenjiProtocol.java @@ -24,10 +24,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class KenjiProtocol extends BaseProtocol { - public KenjiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public KenjiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/KhdProtocol.java b/src/main/java/org/traccar/protocol/KhdProtocol.java index 835d4ea0b..521274de5 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocol.java +++ b/src/main/java/org/traccar/protocol/KhdProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class KhdProtocol extends BaseProtocol { - public KhdProtocol() { + @Inject + public KhdProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, @@ -34,7 +37,7 @@ public class KhdProtocol extends BaseProtocol { Command.TYPE_SET_ODOMETER, Command.TYPE_POSITION_SINGLE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(512, 3, 2)); diff --git a/src/main/java/org/traccar/protocol/L100Protocol.java b/src/main/java/org/traccar/protocol/L100Protocol.java index 44770c316..0edea6095 100644 --- a/src/main/java/org/traccar/protocol/L100Protocol.java +++ b/src/main/java/org/traccar/protocol/L100Protocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class L100Protocol extends BaseProtocol { - public L100Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public L100Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new L100FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/LacakProtocol.java b/src/main/java/org/traccar/protocol/LacakProtocol.java index a22ba609d..bbebd51ed 100644 --- a/src/main/java/org/traccar/protocol/LacakProtocol.java +++ b/src/main/java/org/traccar/protocol/LacakProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class LacakProtocol extends BaseProtocol { - public LacakProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public LacakProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocol.java b/src/main/java/org/traccar/protocol/LaipacProtocol.java index 973dcac06..249d3bcbe 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocol.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocol.java @@ -24,16 +24,19 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class LaipacProtocol extends BaseProtocol { - public LaipacProtocol() { + @Inject + public LaipacProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java index b121da2df..7e13e23d0 100644 --- a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java @@ -24,10 +24,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class LeafSpyProtocol extends BaseProtocol { - public LeafSpyProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public LeafSpyProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/M2cProtocol.java b/src/main/java/org/traccar/protocol/M2cProtocol.java index 696823460..a23ea0f57 100644 --- a/src/main/java/org/traccar/protocol/M2cProtocol.java +++ b/src/main/java/org/traccar/protocol/M2cProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class M2cProtocol extends BaseProtocol { - public M2cProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public M2cProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, ']')); diff --git a/src/main/java/org/traccar/protocol/M2mProtocol.java b/src/main/java/org/traccar/protocol/M2mProtocol.java index e21b61b91..6809d800c 100644 --- a/src/main/java/org/traccar/protocol/M2mProtocol.java +++ b/src/main/java/org/traccar/protocol/M2mProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class M2mProtocol extends BaseProtocol { - public M2mProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public M2mProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(23)); diff --git a/src/main/java/org/traccar/protocol/MaestroProtocol.java b/src/main/java/org/traccar/protocol/MaestroProtocol.java index 536f50448..38a67f9a4 100644 --- a/src/main/java/org/traccar/protocol/MaestroProtocol.java +++ b/src/main/java/org/traccar/protocol/MaestroProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MaestroProtocol extends BaseProtocol { - public MaestroProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MaestroProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(160)); diff --git a/src/main/java/org/traccar/protocol/ManPowerProtocol.java b/src/main/java/org/traccar/protocol/ManPowerProtocol.java index 8e640d137..492e86605 100644 --- a/src/main/java/org/traccar/protocol/ManPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ManPowerProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ManPowerProtocol extends BaseProtocol { - public ManPowerProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ManPowerProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';')); diff --git a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java index 6e92d0809..cf65a2db3 100644 --- a/src/main/java/org/traccar/protocol/Mavlink2Protocol.java +++ b/src/main/java/org/traccar/protocol/Mavlink2Protocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Mavlink2Protocol extends BaseProtocol { - public Mavlink2Protocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public Mavlink2Protocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 1, 10, 0)); diff --git a/src/main/java/org/traccar/protocol/MegastekProtocol.java b/src/main/java/org/traccar/protocol/MegastekProtocol.java index 130697859..10215eb7c 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocol.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MegastekProtocol extends BaseProtocol { - public MegastekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MegastekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MegastekFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java index 6ef13c51f..2c853f0e1 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java @@ -21,9 +21,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class MeiligaoProtocol extends BaseProtocol { - public MeiligaoProtocol() { + @Inject + public MeiligaoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, @@ -33,7 +36,7 @@ public class MeiligaoProtocol extends BaseProtocol { Command.TYPE_SET_TIMEZONE, Command.TYPE_REQUEST_PHOTO, Command.TYPE_REBOOT_DEVICE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeiligaoFrameDecoder()); @@ -41,7 +44,7 @@ public class MeiligaoProtocol extends BaseProtocol { pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocol.java b/src/main/java/org/traccar/protocol/MeitrackProtocol.java index 6503fa5e2..c6eba8fe1 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class MeitrackProtocol extends BaseProtocol { - public MeitrackProtocol() { + @Inject + public MeitrackProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, @@ -33,7 +36,7 @@ public class MeitrackProtocol extends BaseProtocol { Command.TYPE_ALARM_DISARM, Command.TYPE_REQUEST_PHOTO, Command.TYPE_SEND_SMS); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MeitrackFrameDecoder()); @@ -42,7 +45,7 @@ public class MeitrackProtocol extends BaseProtocol { pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/MictrackProtocol.java b/src/main/java/org/traccar/protocol/MictrackProtocol.java index 0d1b26909..ccbc4db4c 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MictrackProtocol extends BaseProtocol { - public MictrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MictrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); @@ -33,7 +36,7 @@ public class MictrackProtocol extends BaseProtocol { pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/MilesmateProtocol.java b/src/main/java/org/traccar/protocol/MilesmateProtocol.java index cc059c520..59212e791 100644 --- a/src/main/java/org/traccar/protocol/MilesmateProtocol.java +++ b/src/main/java/org/traccar/protocol/MilesmateProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MilesmateProtocol extends BaseProtocol { - public MilesmateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MilesmateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java index 182b5cd91..44599accc 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java @@ -24,9 +24,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class MiniFinderProtocol extends BaseProtocol { - public MiniFinderProtocol() { + @Inject + public MiniFinderProtocol(Config config) { setSupportedDataCommands( Command.TYPE_SET_TIMEZONE, Command.TYPE_VOICE_MONITORING, @@ -39,7 +42,7 @@ public class MiniFinderProtocol extends BaseProtocol { Command.TYPE_MODE_DEEP_SLEEP, Command.TYPE_SOS_NUMBER, Command.TYPE_SET_INDICATOR); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ";\0", ";")); diff --git a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java index 82341e9d0..5499a274e 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2Protocol.java +++ b/src/main/java/org/traccar/protocol/Minifinder2Protocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class Minifinder2Protocol extends BaseProtocol { - public Minifinder2Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Minifinder2Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1200, 2, 2, 4, 0, true)); diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocol.java b/src/main/java/org/traccar/protocol/MobilogixProtocol.java index 37e3d9131..1b06c2249 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocol.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MobilogixProtocol extends BaseProtocol { - public MobilogixProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MobilogixProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ']')); diff --git a/src/main/java/org/traccar/protocol/MoovboxProtocol.java b/src/main/java/org/traccar/protocol/MoovboxProtocol.java index 00fcac6ed..16438e122 100644 --- a/src/main/java/org/traccar/protocol/MoovboxProtocol.java +++ b/src/main/java/org/traccar/protocol/MoovboxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MoovboxProtocol extends BaseProtocol { - public MoovboxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MoovboxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/MotorProtocol.java b/src/main/java/org/traccar/protocol/MotorProtocol.java index d168835bb..3101c9b75 100644 --- a/src/main/java/org/traccar/protocol/MotorProtocol.java +++ b/src/main/java/org/traccar/protocol/MotorProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MotorProtocol extends BaseProtocol { - public MotorProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MotorProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Mta6Protocol.java b/src/main/java/org/traccar/protocol/Mta6Protocol.java index 689ee65dd..019fe4fa9 100644 --- a/src/main/java/org/traccar/protocol/Mta6Protocol.java +++ b/src/main/java/org/traccar/protocol/Mta6Protocol.java @@ -24,10 +24,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.config.Keys; +import javax.inject.Inject; + public class Mta6Protocol extends BaseProtocol { - public Mta6Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Mta6Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/MtxProtocol.java b/src/main/java/org/traccar/protocol/MtxProtocol.java index c22eb4b96..e085b6221 100644 --- a/src/main/java/org/traccar/protocol/MtxProtocol.java +++ b/src/main/java/org/traccar/protocol/MtxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MtxProtocol extends BaseProtocol { - public MtxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MtxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/MxtProtocol.java b/src/main/java/org/traccar/protocol/MxtProtocol.java index 8269f3f2c..1190bf527 100644 --- a/src/main/java/org/traccar/protocol/MxtProtocol.java +++ b/src/main/java/org/traccar/protocol/MxtProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class MxtProtocol extends BaseProtocol { - public MxtProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public MxtProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new MxtFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NavigilProtocol.java b/src/main/java/org/traccar/protocol/NavigilProtocol.java index e5e3417e9..46a6c33a5 100644 --- a/src/main/java/org/traccar/protocol/NavigilProtocol.java +++ b/src/main/java/org/traccar/protocol/NavigilProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NavigilProtocol extends BaseProtocol { - public NavigilProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavigilProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavigilFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NavisProtocol.java b/src/main/java/org/traccar/protocol/NavisProtocol.java index 146f0cc9f..640a77803 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NavisProtocol extends BaseProtocol { - public NavisProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavisProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavisFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NavisetProtocol.java b/src/main/java/org/traccar/protocol/NavisetProtocol.java index 6423dd401..388f141f8 100644 --- a/src/main/java/org/traccar/protocol/NavisetProtocol.java +++ b/src/main/java/org/traccar/protocol/NavisetProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NavisetProtocol extends BaseProtocol { - public NavisetProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavisetProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavisetFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java index dfc08ece2..50013d1a4 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocol.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NavtelecomProtocol extends BaseProtocol { - public NavtelecomProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NavtelecomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NavtelecomFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NeosProtocol.java b/src/main/java/org/traccar/protocol/NeosProtocol.java index a3d79f833..0787b6562 100644 --- a/src/main/java/org/traccar/protocol/NeosProtocol.java +++ b/src/main/java/org/traccar/protocol/NeosProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NeosProtocol extends BaseProtocol { - public NeosProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public NeosProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/NetProtocol.java b/src/main/java/org/traccar/protocol/NetProtocol.java index c39e07337..f27e4afb8 100644 --- a/src/main/java/org/traccar/protocol/NetProtocol.java +++ b/src/main/java/org/traccar/protocol/NetProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NetProtocol extends BaseProtocol { - public NetProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NetProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '!')); diff --git a/src/main/java/org/traccar/protocol/NiotProtocol.java b/src/main/java/org/traccar/protocol/NiotProtocol.java index 659395638..0fbe0c689 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocol.java +++ b/src/main/java/org/traccar/protocol/NiotProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NiotProtocol extends BaseProtocol { - public NiotProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NiotProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2)); diff --git a/src/main/java/org/traccar/protocol/NoranProtocol.java b/src/main/java/org/traccar/protocol/NoranProtocol.java index adeab8a75..626991029 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocol.java +++ b/src/main/java/org/traccar/protocol/NoranProtocol.java @@ -21,16 +21,19 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class NoranProtocol extends BaseProtocol { - public NoranProtocol() { + @Inject + public NoranProtocol(Config config) { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_POSITION_STOP, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NoranProtocolEncoder(NoranProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/NvsProtocol.java b/src/main/java/org/traccar/protocol/NvsProtocol.java index 594b2c325..7ed488e38 100644 --- a/src/main/java/org/traccar/protocol/NvsProtocol.java +++ b/src/main/java/org/traccar/protocol/NvsProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class NvsProtocol extends BaseProtocol { - public NvsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NvsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new NvsFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/NyitechProtocol.java b/src/main/java/org/traccar/protocol/NyitechProtocol.java index da0a0331c..e7ef10945 100644 --- a/src/main/java/org/traccar/protocol/NyitechProtocol.java +++ b/src/main/java/org/traccar/protocol/NyitechProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class NyitechProtocol extends BaseProtocol { - public NyitechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public NyitechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true)); diff --git a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java index b8ea7433a..94f450426 100644 --- a/src/main/java/org/traccar/protocol/ObdDongleProtocol.java +++ b/src/main/java/org/traccar/protocol/ObdDongleProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ObdDongleProtocol extends BaseProtocol { - public ObdDongleProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ObdDongleProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1099, 20, 2, 3, 0)); diff --git a/src/main/java/org/traccar/protocol/OigoProtocol.java b/src/main/java/org/traccar/protocol/OigoProtocol.java index 02d5c40ff..0539bada6 100644 --- a/src/main/java/org/traccar/protocol/OigoProtocol.java +++ b/src/main/java/org/traccar/protocol/OigoProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OigoProtocol extends BaseProtocol { - public OigoProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public OigoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OigoProtocolDecoder(OigoProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/OkoProtocol.java b/src/main/java/org/traccar/protocol/OkoProtocol.java index 70ea65a29..29c8bc1b9 100644 --- a/src/main/java/org/traccar/protocol/OkoProtocol.java +++ b/src/main/java/org/traccar/protocol/OkoProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OkoProtocol extends BaseProtocol { - public OkoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OkoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '}')); diff --git a/src/main/java/org/traccar/protocol/OmnicommProtocol.java b/src/main/java/org/traccar/protocol/OmnicommProtocol.java index 81a7b30ac..dd400c779 100644 --- a/src/main/java/org/traccar/protocol/OmnicommProtocol.java +++ b/src/main/java/org/traccar/protocol/OmnicommProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OmnicommProtocol extends BaseProtocol { - public OmnicommProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OmnicommProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OmnicommFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java index 1eed96eed..5443b4ffc 100644 --- a/src/main/java/org/traccar/protocol/OpenGtsProtocol.java +++ b/src/main/java/org/traccar/protocol/OpenGtsProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OpenGtsProtocol extends BaseProtocol { - public OpenGtsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OpenGtsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocol.java b/src/main/java/org/traccar/protocol/OrbcommProtocol.java index 4f27b1efe..fb09f0abb 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocol.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerClient; import org.traccar.config.Config; +import javax.inject.Inject; + public class OrbcommProtocol extends BaseProtocol { - public OrbcommProtocol() { - addClient(new TrackerClient(getName()) { + @Inject + public OrbcommProtocol(Config config) { + addClient(new TrackerClient(config, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpRequestEncoder()); diff --git a/src/main/java/org/traccar/protocol/OrionProtocol.java b/src/main/java/org/traccar/protocol/OrionProtocol.java index cb92f10b7..2dec7cd06 100644 --- a/src/main/java/org/traccar/protocol/OrionProtocol.java +++ b/src/main/java/org/traccar/protocol/OrionProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OrionProtocol extends BaseProtocol { - public OrionProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OrionProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new OrionFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocol.java b/src/main/java/org/traccar/protocol/OsmAndProtocol.java index 3281a8ae4..a86bc70d7 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocol.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OsmAndProtocol extends BaseProtocol { - public OsmAndProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OsmAndProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocol.java b/src/main/java/org/traccar/protocol/OutsafeProtocol.java index ae7cb881f..0099be456 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocol.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OutsafeProtocol extends BaseProtocol { - public OutsafeProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OutsafeProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java index c444f453e..9ad337f19 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocol.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocol.java @@ -24,10 +24,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class OwnTracksProtocol extends BaseProtocol { - public OwnTracksProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public OwnTracksProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java index c8b046f41..709729ef1 100644 --- a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PacificTrackProtocol extends BaseProtocol { - public PacificTrackProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public PacificTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PacificTrackProtocolDecoder(PacificTrackProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/PathAwayProtocol.java b/src/main/java/org/traccar/protocol/PathAwayProtocol.java index a2f152dda..1d13eea95 100644 --- a/src/main/java/org/traccar/protocol/PathAwayProtocol.java +++ b/src/main/java/org/traccar/protocol/PathAwayProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PathAwayProtocol extends BaseProtocol { - public PathAwayProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PathAwayProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocol.java b/src/main/java/org/traccar/protocol/PiligrimProtocol.java index 7c0ecaf30..aa45a0def 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocol.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PiligrimProtocol extends BaseProtocol { - public PiligrimProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PiligrimProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/PluginProtocol.java b/src/main/java/org/traccar/protocol/PluginProtocol.java index 2d21f8b41..b2101b18d 100644 --- a/src/main/java/org/traccar/protocol/PluginProtocol.java +++ b/src/main/java/org/traccar/protocol/PluginProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PluginProtocol extends BaseProtocol { - public PluginProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PluginProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/PolteProtocol.java b/src/main/java/org/traccar/protocol/PolteProtocol.java index 47c64e5ba..69666cc0e 100644 --- a/src/main/java/org/traccar/protocol/PolteProtocol.java +++ b/src/main/java/org/traccar/protocol/PolteProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PolteProtocol extends BaseProtocol { - public PolteProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PolteProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/PortmanProtocol.java b/src/main/java/org/traccar/protocol/PortmanProtocol.java index 875c0a599..de78013fa 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocol.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocol.java @@ -24,13 +24,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class PortmanProtocol extends BaseProtocol { - public PortmanProtocol() { + @Inject + public PortmanProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/PretraceProtocol.java b/src/main/java/org/traccar/protocol/PretraceProtocol.java index db1b6d918..b77dd97bf 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocol.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocol.java @@ -24,13 +24,16 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class PretraceProtocol extends BaseProtocol { - public PretraceProtocol() { + @Inject + public PretraceProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_PERIODIC); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); diff --git a/src/main/java/org/traccar/protocol/PricolProtocol.java b/src/main/java/org/traccar/protocol/PricolProtocol.java index b009662ac..f5e904541 100644 --- a/src/main/java/org/traccar/protocol/PricolProtocol.java +++ b/src/main/java/org/traccar/protocol/PricolProtocol.java @@ -21,17 +21,20 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class PricolProtocol extends BaseProtocol { - public PricolProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public PricolProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new FixedLengthFrameDecoder(64)); pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PricolProtocolDecoder(PricolProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/ProgressProtocol.java b/src/main/java/org/traccar/protocol/ProgressProtocol.java index 235ae1c5e..49eb6847f 100644 --- a/src/main/java/org/traccar/protocol/ProgressProtocol.java +++ b/src/main/java/org/traccar/protocol/ProgressProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class ProgressProtocol extends BaseProtocol { - public ProgressProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ProgressProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, 4, 0, true)); diff --git a/src/main/java/org/traccar/protocol/PstProtocol.java b/src/main/java/org/traccar/protocol/PstProtocol.java index e1f3e18ce..73f978cbd 100644 --- a/src/main/java/org/traccar/protocol/PstProtocol.java +++ b/src/main/java/org/traccar/protocol/PstProtocol.java @@ -21,20 +21,23 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class PstProtocol extends BaseProtocol { - public PstProtocol() { + @Inject + public PstProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PstProtocolEncoder(PstProtocol.this)); pipeline.addLast(new PstProtocolDecoder(PstProtocol.this)); } }); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new PstFrameEncoder()); diff --git a/src/main/java/org/traccar/protocol/Pt215Protocol.java b/src/main/java/org/traccar/protocol/Pt215Protocol.java index c134afa51..b272582a4 100644 --- a/src/main/java/org/traccar/protocol/Pt215Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt215Protocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Pt215Protocol extends BaseProtocol { - public Pt215Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Pt215Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 1, -1, 0)); diff --git a/src/main/java/org/traccar/protocol/Pt3000Protocol.java b/src/main/java/org/traccar/protocol/Pt3000Protocol.java index 1f783481b..d72774f47 100644 --- a/src/main/java/org/traccar/protocol/Pt3000Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt3000Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Pt3000Protocol extends BaseProtocol { - public Pt3000Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Pt3000Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, 'd')); // probably wrong diff --git a/src/main/java/org/traccar/protocol/Pt502Protocol.java b/src/main/java/org/traccar/protocol/Pt502Protocol.java index 64ff4fe06..d5d30e8e8 100644 --- a/src/main/java/org/traccar/protocol/Pt502Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt502Protocol.java @@ -22,16 +22,19 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Pt502Protocol extends BaseProtocol { - public Pt502Protocol() { + @Inject + public Pt502Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_SET_TIMEZONE, Command.TYPE_ALARM_SPEED, Command.TYPE_OUTPUT_CONTROL, Command.TYPE_REQUEST_PHOTO); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Pt502FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Pt60Protocol.java b/src/main/java/org/traccar/protocol/Pt60Protocol.java index 45084a2f3..58345f025 100644 --- a/src/main/java/org/traccar/protocol/Pt60Protocol.java +++ b/src/main/java/org/traccar/protocol/Pt60Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Pt60Protocol extends BaseProtocol { - public Pt60Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Pt60Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "@R#@", "@E#@")); diff --git a/src/main/java/org/traccar/protocol/R12wProtocol.java b/src/main/java/org/traccar/protocol/R12wProtocol.java index f3464a3a3..a406f6306 100644 --- a/src/main/java/org/traccar/protocol/R12wProtocol.java +++ b/src/main/java/org/traccar/protocol/R12wProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class R12wProtocol extends BaseProtocol { - public R12wProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public R12wProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java index 7c7b9a87d..63ca3476c 100644 --- a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java +++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RaceDynamicsProtocol extends BaseProtocol { - public RaceDynamicsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RaceDynamicsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1500)); diff --git a/src/main/java/org/traccar/protocol/RadarProtocol.java b/src/main/java/org/traccar/protocol/RadarProtocol.java index 0b3d836a5..9d88c6d72 100644 --- a/src/main/java/org/traccar/protocol/RadarProtocol.java +++ b/src/main/java/org/traccar/protocol/RadarProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RadarProtocol extends BaseProtocol { - public RadarProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RadarProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 12, 2, -14, 0)); diff --git a/src/main/java/org/traccar/protocol/RaveonProtocol.java b/src/main/java/org/traccar/protocol/RaveonProtocol.java index 5a1bb88d2..db70396ee 100644 --- a/src/main/java/org/traccar/protocol/RaveonProtocol.java +++ b/src/main/java/org/traccar/protocol/RaveonProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RaveonProtocol extends BaseProtocol { - public RaveonProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RaveonProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/RecodaProtocol.java b/src/main/java/org/traccar/protocol/RecodaProtocol.java index 9ae837a88..0d50db01e 100644 --- a/src/main/java/org/traccar/protocol/RecodaProtocol.java +++ b/src/main/java/org/traccar/protocol/RecodaProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class RecodaProtocol extends BaseProtocol { - public RecodaProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RecodaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 4, 4, -8, 0, true)); diff --git a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java index efea6013e..1d4b419bb 100644 --- a/src/main/java/org/traccar/protocol/RetranslatorProtocol.java +++ b/src/main/java/org/traccar/protocol/RetranslatorProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RetranslatorProtocol extends BaseProtocol { - public RetranslatorProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RetranslatorProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new RetranslatorFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/RitiProtocol.java b/src/main/java/org/traccar/protocol/RitiProtocol.java index 34c4015b2..9b9c00cb2 100644 --- a/src/main/java/org/traccar/protocol/RitiProtocol.java +++ b/src/main/java/org/traccar/protocol/RitiProtocol.java @@ -22,10 +22,13 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class RitiProtocol extends BaseProtocol { - public RitiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RitiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 105, 2, 3, 0, true)); diff --git a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java index 099136272..ab2bc5842 100644 --- a/src/main/java/org/traccar/protocol/RoboTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/RoboTrackProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RoboTrackProtocol extends BaseProtocol { - public RoboTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public RoboTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new RoboTrackFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/RstProtocol.java b/src/main/java/org/traccar/protocol/RstProtocol.java index 3a52a215e..109d91b16 100644 --- a/src/main/java/org/traccar/protocol/RstProtocol.java +++ b/src/main/java/org/traccar/protocol/RstProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class RstProtocol extends BaseProtocol { - public RstProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public RstProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocol.java b/src/main/java/org/traccar/protocol/RuptelaProtocol.java index 59c5f7942..99a9686f6 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocol.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class RuptelaProtocol extends BaseProtocol { - public RuptelaProtocol() { + @Inject + public RuptelaProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ENGINE_STOP, @@ -36,7 +39,7 @@ public class RuptelaProtocol extends BaseProtocol { Command.TYPE_OUTPUT_CONTROL, Command.TYPE_SET_CONNECTION, Command.TYPE_SET_ODOMETER); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 2, 0)); diff --git a/src/main/java/org/traccar/protocol/S168Protocol.java b/src/main/java/org/traccar/protocol/S168Protocol.java index 7186ce93d..f904ed9ff 100644 --- a/src/main/java/org/traccar/protocol/S168Protocol.java +++ b/src/main/java/org/traccar/protocol/S168Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class S168Protocol extends BaseProtocol { - public S168Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public S168Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); diff --git a/src/main/java/org/traccar/protocol/SabertekProtocol.java b/src/main/java/org/traccar/protocol/SabertekProtocol.java index 9c66fd50d..403243cdc 100644 --- a/src/main/java/org/traccar/protocol/SabertekProtocol.java +++ b/src/main/java/org/traccar/protocol/SabertekProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SabertekProtocol extends BaseProtocol { - public SabertekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SabertekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SabertekFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/SanavProtocol.java b/src/main/java/org/traccar/protocol/SanavProtocol.java index e067a2469..1a0e7b0e9 100644 --- a/src/main/java/org/traccar/protocol/SanavProtocol.java +++ b/src/main/java/org/traccar/protocol/SanavProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SanavProtocol extends BaseProtocol { - public SanavProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SanavProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); @@ -33,7 +36,7 @@ public class SanavProtocol extends BaseProtocol { pipeline.addLast(new SanavProtocolDecoder(SanavProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/SanulProtocol.java b/src/main/java/org/traccar/protocol/SanulProtocol.java index 3c268d984..ea44bf868 100644 --- a/src/main/java/org/traccar/protocol/SanulProtocol.java +++ b/src/main/java/org/traccar/protocol/SanulProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class SanulProtocol extends BaseProtocol { - public SanulProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SanulProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 3, 2, 0, 0, true)); diff --git a/src/main/java/org/traccar/protocol/SatsolProtocol.java b/src/main/java/org/traccar/protocol/SatsolProtocol.java index 15a43f94d..d90033e38 100644 --- a/src/main/java/org/traccar/protocol/SatsolProtocol.java +++ b/src/main/java/org/traccar/protocol/SatsolProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class SatsolProtocol extends BaseProtocol { - public SatsolProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SatsolProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1400, 8, 2, 0, 0, true)); diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocol.java b/src/main/java/org/traccar/protocol/SigfoxProtocol.java index 7666f5589..9a268af62 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocol.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SigfoxProtocol extends BaseProtocol { - public SigfoxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SigfoxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/SiwiProtocol.java b/src/main/java/org/traccar/protocol/SiwiProtocol.java index 4cb441e8a..f12958a50 100644 --- a/src/main/java/org/traccar/protocol/SiwiProtocol.java +++ b/src/main/java/org/traccar/protocol/SiwiProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SiwiProtocol extends BaseProtocol { - public SiwiProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SiwiProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java index 91830504e..7ae26f634 100644 --- a/src/main/java/org/traccar/protocol/SkypatrolProtocol.java +++ b/src/main/java/org/traccar/protocol/SkypatrolProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SkypatrolProtocol extends BaseProtocol { - public SkypatrolProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public SkypatrolProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SkypatrolProtocolDecoder(SkypatrolProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java index 6ae341db3..cb7efb7ee 100644 --- a/src/main/java/org/traccar/protocol/SmartSoleProtocol.java +++ b/src/main/java/org/traccar/protocol/SmartSoleProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SmartSoleProtocol extends BaseProtocol { - public SmartSoleProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SmartSoleProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '$')); diff --git a/src/main/java/org/traccar/protocol/SmokeyProtocol.java b/src/main/java/org/traccar/protocol/SmokeyProtocol.java index dc7da9ab5..22b343537 100644 --- a/src/main/java/org/traccar/protocol/SmokeyProtocol.java +++ b/src/main/java/org/traccar/protocol/SmokeyProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SmokeyProtocol extends BaseProtocol { - public SmokeyProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public SmokeyProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SmokeyProtocolDecoder(SmokeyProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java index 9f9ef5a87..0676aa629 100644 --- a/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java +++ b/src/main/java/org/traccar/protocol/SolarPoweredProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SolarPoweredProtocol extends BaseProtocol { - public SolarPoweredProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SolarPoweredProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HuabaoFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/SpotProtocol.java b/src/main/java/org/traccar/protocol/SpotProtocol.java index 238dc3b72..6bd802fed 100644 --- a/src/main/java/org/traccar/protocol/SpotProtocol.java +++ b/src/main/java/org/traccar/protocol/SpotProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SpotProtocol extends BaseProtocol { - public SpotProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SpotProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new HttpResponseEncoder()); diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocol.java b/src/main/java/org/traccar/protocol/StarLinkProtocol.java index fa9cdc30a..d578fa705 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocol.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class StarLinkProtocol extends BaseProtocol { - public StarLinkProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public StarLinkProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/StarcomProtocol.java b/src/main/java/org/traccar/protocol/StarcomProtocol.java index 8f1c4bc3f..33c3a4776 100644 --- a/src/main/java/org/traccar/protocol/StarcomProtocol.java +++ b/src/main/java/org/traccar/protocol/StarcomProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class StarcomProtocol extends BaseProtocol { - public StarcomProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public StarcomProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/StartekProtocol.java b/src/main/java/org/traccar/protocol/StartekProtocol.java index 14ae1564e..d010df858 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocol.java +++ b/src/main/java/org/traccar/protocol/StartekProtocol.java @@ -24,15 +24,18 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class StartekProtocol extends BaseProtocol { - public StartekProtocol() { + @Inject + public StartekProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_OUTPUT_CONTROL, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/StbProtocol.java b/src/main/java/org/traccar/protocol/StbProtocol.java index 206b29e29..af4e0d2c4 100644 --- a/src/main/java/org/traccar/protocol/StbProtocol.java +++ b/src/main/java/org/traccar/protocol/StbProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class StbProtocol extends BaseProtocol { - public StbProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public StbProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Stl060Protocol.java b/src/main/java/org/traccar/protocol/Stl060Protocol.java index 0ac0490e3..83b5db3bb 100644 --- a/src/main/java/org/traccar/protocol/Stl060Protocol.java +++ b/src/main/java/org/traccar/protocol/Stl060Protocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Stl060Protocol extends BaseProtocol { - public Stl060Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Stl060Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Stl060FrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocol.java b/src/main/java/org/traccar/protocol/SuntechProtocol.java index ae55d2a14..4253b761b 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocol.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class SuntechProtocol extends BaseProtocol { - public SuntechProtocol() { + @Inject + public SuntechProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL, Command.TYPE_REBOOT_DEVICE, @@ -33,7 +36,7 @@ public class SuntechProtocol extends BaseProtocol { Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new SuntechFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/SupermateProtocol.java b/src/main/java/org/traccar/protocol/SupermateProtocol.java index 59c68d7d0..4290b7126 100644 --- a/src/main/java/org/traccar/protocol/SupermateProtocol.java +++ b/src/main/java/org/traccar/protocol/SupermateProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SupermateProtocol extends BaseProtocol { - public SupermateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SupermateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "#")); diff --git a/src/main/java/org/traccar/protocol/SviasProtocol.java b/src/main/java/org/traccar/protocol/SviasProtocol.java index d9b413a9e..7c6624f7c 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocol.java +++ b/src/main/java/org/traccar/protocol/SviasProtocol.java @@ -24,9 +24,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class SviasProtocol extends BaseProtocol { - public SviasProtocol() { + @Inject + public SviasProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, @@ -36,7 +39,7 @@ public class SviasProtocol extends BaseProtocol { Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, Command.TYPE_ALARM_REMOVE); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "]")); diff --git a/src/main/java/org/traccar/protocol/SwiftechProtocol.java b/src/main/java/org/traccar/protocol/SwiftechProtocol.java index 3222a7038..68cf40d84 100644 --- a/src/main/java/org/traccar/protocol/SwiftechProtocol.java +++ b/src/main/java/org/traccar/protocol/SwiftechProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class SwiftechProtocol extends BaseProtocol { - public SwiftechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public SwiftechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/T55Protocol.java b/src/main/java/org/traccar/protocol/T55Protocol.java index f3f7b4a74..cedac275f 100644 --- a/src/main/java/org/traccar/protocol/T55Protocol.java +++ b/src/main/java/org/traccar/protocol/T55Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class T55Protocol extends BaseProtocol { - public T55Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public T55Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); @@ -35,7 +38,7 @@ public class T55Protocol extends BaseProtocol { pipeline.addLast(new T55ProtocolDecoder(T55Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/T57Protocol.java b/src/main/java/org/traccar/protocol/T57Protocol.java index e228c5c0d..4bafe8c6d 100644 --- a/src/main/java/org/traccar/protocol/T57Protocol.java +++ b/src/main/java/org/traccar/protocol/T57Protocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class T57Protocol extends BaseProtocol { - public T57Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public T57Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new T57FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/T800xProtocol.java b/src/main/java/org/traccar/protocol/T800xProtocol.java index a6f5f1514..253c3cb73 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocol.java +++ b/src/main/java/org/traccar/protocol/T800xProtocol.java @@ -22,12 +22,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class T800xProtocol extends BaseProtocol { - public T800xProtocol() { + @Inject + public T800xProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, -5, 0)); @@ -35,7 +38,7 @@ public class T800xProtocol extends BaseProtocol { pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new T800xProtocolEncoder(T800xProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TaipProtocol.java b/src/main/java/org/traccar/protocol/TaipProtocol.java index caa4f4c97..943ec98c5 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocol.java +++ b/src/main/java/org/traccar/protocol/TaipProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TaipProtocol extends BaseProtocol { - public TaipProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TaipProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '<')); @@ -36,7 +39,7 @@ public class TaipProtocol extends BaseProtocol { pipeline.addLast(new TaipProtocolDecoder(TaipProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TaipPrefixEncoder(TaipProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TechTltProtocol.java b/src/main/java/org/traccar/protocol/TechTltProtocol.java index e421990a7..191dd9ccc 100644 --- a/src/main/java/org/traccar/protocol/TechTltProtocol.java +++ b/src/main/java/org/traccar/protocol/TechTltProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TechTltProtocol extends BaseProtocol { - public TechTltProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public TechTltProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java index 48ea825a5..265a3eb64 100644 --- a/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java +++ b/src/main/java/org/traccar/protocol/TechtoCruzProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TechtoCruzProtocol extends BaseProtocol { - public TechtoCruzProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TechtoCruzProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TechtoCruzFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/TekProtocol.java b/src/main/java/org/traccar/protocol/TekProtocol.java index 0aeab9be3..54e860d79 100644 --- a/src/main/java/org/traccar/protocol/TekProtocol.java +++ b/src/main/java/org/traccar/protocol/TekProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TekProtocol extends BaseProtocol { - public TekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TekFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/TelemaxProtocol.java b/src/main/java/org/traccar/protocol/TelemaxProtocol.java index 9bbdf7ad7..9e9cbb50e 100644 --- a/src/main/java/org/traccar/protocol/TelemaxProtocol.java +++ b/src/main/java/org/traccar/protocol/TelemaxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TelemaxProtocol extends BaseProtocol { - public TelemaxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TelemaxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/TelicProtocol.java b/src/main/java/org/traccar/protocol/TelicProtocol.java index 6d47a7a7f..9ef7864ca 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocol.java +++ b/src/main/java/org/traccar/protocol/TelicProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TelicProtocol extends BaseProtocol { - public TelicProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TelicProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TelicFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java index e2ee8ef19..38283cb64 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class TeltonikaProtocol extends BaseProtocol { - public TeltonikaProtocol() { + @Inject + public TeltonikaProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TeltonikaFrameDecoder()); @@ -34,7 +37,7 @@ public class TeltonikaProtocol extends BaseProtocol { pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java index 8b62db8c0..73219cc5e 100644 --- a/src/main/java/org/traccar/protocol/TeraTrackProtocol.java +++ b/src/main/java/org/traccar/protocol/TeraTrackProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TeraTrackProtocol extends BaseProtocol { - public TeraTrackProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TeraTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new JsonFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java index 076386818..38bf078aa 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ThinkPowerProtocol extends BaseProtocol { - public ThinkPowerProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ThinkPowerProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, 2, 0)); diff --git a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java index 6c684a8b4..782b0a352 100644 --- a/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java +++ b/src/main/java/org/traccar/protocol/ThinkRaceProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class ThinkRaceProtocol extends BaseProtocol { - public ThinkRaceProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public ThinkRaceProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2 + 12 + 1 + 1, 2, 2, 0)); diff --git a/src/main/java/org/traccar/protocol/Tk102Protocol.java b/src/main/java/org/traccar/protocol/Tk102Protocol.java index 8eb923d50..150e83ab3 100644 --- a/src/main/java/org/traccar/protocol/Tk102Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk102Protocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Tk102Protocol extends BaseProtocol { - public Tk102Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tk102Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1 + 1 + 10, 1, 1, 0)); diff --git a/src/main/java/org/traccar/protocol/Tk103Protocol.java b/src/main/java/org/traccar/protocol/Tk103Protocol.java index bca16928f..cf09886f5 100644 --- a/src/main/java/org/traccar/protocol/Tk103Protocol.java +++ b/src/main/java/org/traccar/protocol/Tk103Protocol.java @@ -24,9 +24,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class Tk103Protocol extends BaseProtocol { - public Tk103Protocol() { + @Inject + public Tk103Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_GET_DEVICE_STATUS, @@ -46,7 +49,7 @@ public class Tk103Protocol extends BaseProtocol { Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Tk103FrameDecoder()); @@ -56,7 +59,7 @@ public class Tk103Protocol extends BaseProtocol { pipeline.addLast(new Tk103ProtocolDecoder(Tk103Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java index 8c8777074..b10271f7d 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Tlt2hProtocol extends BaseProtocol { - public Tlt2hProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tlt2hProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(32 * 1024, "##\r\n")); diff --git a/src/main/java/org/traccar/protocol/TlvProtocol.java b/src/main/java/org/traccar/protocol/TlvProtocol.java index 5b8de8fbe..9d83388c9 100644 --- a/src/main/java/org/traccar/protocol/TlvProtocol.java +++ b/src/main/java/org/traccar/protocol/TlvProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TlvProtocol extends BaseProtocol { - public TlvProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TlvProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\0')); diff --git a/src/main/java/org/traccar/protocol/TmgProtocol.java b/src/main/java/org/traccar/protocol/TmgProtocol.java index 6c29a8854..e078c425b 100644 --- a/src/main/java/org/traccar/protocol/TmgProtocol.java +++ b/src/main/java/org/traccar/protocol/TmgProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TmgProtocol extends BaseProtocol { - public TmgProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TmgProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TmgFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/TopflytechProtocol.java b/src/main/java/org/traccar/protocol/TopflytechProtocol.java index 47162a42d..339d2fc8d 100644 --- a/src/main/java/org/traccar/protocol/TopflytechProtocol.java +++ b/src/main/java/org/traccar/protocol/TopflytechProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TopflytechProtocol extends BaseProtocol { - public TopflytechProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TopflytechProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')')); diff --git a/src/main/java/org/traccar/protocol/TopinProtocol.java b/src/main/java/org/traccar/protocol/TopinProtocol.java index 3c1a7eed3..b15373d71 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocol.java +++ b/src/main/java/org/traccar/protocol/TopinProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class TopinProtocol extends BaseProtocol { - public TopinProtocol() { + @Inject + public TopinProtocol(Config config) { setSupportedDataCommands( Command.TYPE_SOS_NUMBER); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TopinProtocolEncoder(TopinProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java index 3322d1dc0..9ab36fd0b 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocol.java +++ b/src/main/java/org/traccar/protocol/TotemProtocol.java @@ -23,9 +23,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class TotemProtocol extends BaseProtocol { - public TotemProtocol() { + @Inject + public TotemProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_REBOOT_DEVICE, @@ -47,7 +50,7 @@ public class TotemProtocol extends BaseProtocol { Command.TYPE_ENGINE_STOP ); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TotemFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/Tr20Protocol.java b/src/main/java/org/traccar/protocol/Tr20Protocol.java index dc6c013c8..615fdab28 100644 --- a/src/main/java/org/traccar/protocol/Tr20Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr20Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Tr20Protocol extends BaseProtocol { - public Tr20Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tr20Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); @@ -35,7 +38,7 @@ public class Tr20Protocol extends BaseProtocol { pipeline.addLast(new Tr20ProtocolDecoder(Tr20Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Tr900Protocol.java b/src/main/java/org/traccar/protocol/Tr900Protocol.java index 615987952..162cbe651 100644 --- a/src/main/java/org/traccar/protocol/Tr900Protocol.java +++ b/src/main/java/org/traccar/protocol/Tr900Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Tr900Protocol extends BaseProtocol { - public Tr900Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tr900Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); @@ -35,7 +38,7 @@ public class Tr900Protocol extends BaseProtocol { pipeline.addLast(new Tr900ProtocolDecoder(Tr900Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/TrackboxProtocol.java b/src/main/java/org/traccar/protocol/TrackboxProtocol.java index 1c756e26b..4236144a3 100644 --- a/src/main/java/org/traccar/protocol/TrackboxProtocol.java +++ b/src/main/java/org/traccar/protocol/TrackboxProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TrackboxProtocol extends BaseProtocol { - public TrackboxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TrackboxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/TrakMateProtocol.java b/src/main/java/org/traccar/protocol/TrakMateProtocol.java index 25f6d9470..b7637e6f3 100644 --- a/src/main/java/org/traccar/protocol/TrakMateProtocol.java +++ b/src/main/java/org/traccar/protocol/TrakMateProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TrakMateProtocol extends BaseProtocol { - public TrakMateProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TrakMateProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/TramigoProtocol.java b/src/main/java/org/traccar/protocol/TramigoProtocol.java index 2c8013523..79a59abd3 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocol.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TramigoProtocol extends BaseProtocol { - public TramigoProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TramigoProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TramigoFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/TrvProtocol.java b/src/main/java/org/traccar/protocol/TrvProtocol.java index a8884eb5e..e67afbda2 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocol.java +++ b/src/main/java/org/traccar/protocol/TrvProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TrvProtocol extends BaseProtocol { - public TrvProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TrvProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/Tt8850Protocol.java b/src/main/java/org/traccar/protocol/Tt8850Protocol.java index b11411817..ab109e274 100644 --- a/src/main/java/org/traccar/protocol/Tt8850Protocol.java +++ b/src/main/java/org/traccar/protocol/Tt8850Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Tt8850Protocol extends BaseProtocol { - public Tt8850Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Tt8850Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "$")); diff --git a/src/main/java/org/traccar/protocol/TytanProtocol.java b/src/main/java/org/traccar/protocol/TytanProtocol.java index 2ca1ff8e8..cc3bc9b52 100644 --- a/src/main/java/org/traccar/protocol/TytanProtocol.java +++ b/src/main/java/org/traccar/protocol/TytanProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TytanProtocol extends BaseProtocol { - public TytanProtocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public TytanProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new TytanProtocolDecoder(TytanProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/TzoneProtocol.java b/src/main/java/org/traccar/protocol/TzoneProtocol.java index 9bb550e39..d25757b63 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocol.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class TzoneProtocol extends BaseProtocol { - public TzoneProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public TzoneProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(256, 2, 2, 2, 0)); diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocol.java b/src/main/java/org/traccar/protocol/UlbotechProtocol.java index d149bbd58..57fc47644 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocol.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocol.java @@ -21,12 +21,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class UlbotechProtocol extends BaseProtocol { - public UlbotechProtocol() { + @Inject + public UlbotechProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new UlbotechFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/UproProtocol.java b/src/main/java/org/traccar/protocol/UproProtocol.java index 5bfa6d76d..e27088594 100644 --- a/src/main/java/org/traccar/protocol/UproProtocol.java +++ b/src/main/java/org/traccar/protocol/UproProtocol.java @@ -22,10 +22,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class UproProtocol extends BaseProtocol { - public UproProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public UproProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/UuxProtocol.java b/src/main/java/org/traccar/protocol/UuxProtocol.java index 61f622f68..3de4a4732 100644 --- a/src/main/java/org/traccar/protocol/UuxProtocol.java +++ b/src/main/java/org/traccar/protocol/UuxProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class UuxProtocol extends BaseProtocol { - public UuxProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public UuxProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 1)); diff --git a/src/main/java/org/traccar/protocol/V680Protocol.java b/src/main/java/org/traccar/protocol/V680Protocol.java index 488dcc4e0..53bca849c 100644 --- a/src/main/java/org/traccar/protocol/V680Protocol.java +++ b/src/main/java/org/traccar/protocol/V680Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class V680Protocol extends BaseProtocol { - public V680Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public V680Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); @@ -35,7 +38,7 @@ public class V680Protocol extends BaseProtocol { pipeline.addLast(new V680ProtocolDecoder(V680Protocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/VisiontekProtocol.java b/src/main/java/org/traccar/protocol/VisiontekProtocol.java index 5d3e3c097..5296402b4 100644 --- a/src/main/java/org/traccar/protocol/VisiontekProtocol.java +++ b/src/main/java/org/traccar/protocol/VisiontekProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class VisiontekProtocol extends BaseProtocol { - public VisiontekProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public VisiontekProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); diff --git a/src/main/java/org/traccar/protocol/VnetProtocol.java b/src/main/java/org/traccar/protocol/VnetProtocol.java index 41522935e..dd739f0d9 100644 --- a/src/main/java/org/traccar/protocol/VnetProtocol.java +++ b/src/main/java/org/traccar/protocol/VnetProtocol.java @@ -23,10 +23,13 @@ import org.traccar.config.Config; import java.nio.ByteOrder; +import javax.inject.Inject; + public class VnetProtocol extends BaseProtocol { - public VnetProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public VnetProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1500, 4, 2, 12, 0, true)); diff --git a/src/main/java/org/traccar/protocol/Vt200Protocol.java b/src/main/java/org/traccar/protocol/Vt200Protocol.java index 655514e94..efb5fe2fd 100644 --- a/src/main/java/org/traccar/protocol/Vt200Protocol.java +++ b/src/main/java/org/traccar/protocol/Vt200Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Vt200Protocol extends BaseProtocol { - public Vt200Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Vt200Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Vt200FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/VtfmsProtocol.java b/src/main/java/org/traccar/protocol/VtfmsProtocol.java index 8bedd455d..482ab4a37 100644 --- a/src/main/java/org/traccar/protocol/VtfmsProtocol.java +++ b/src/main/java/org/traccar/protocol/VtfmsProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class VtfmsProtocol extends BaseProtocol { - public VtfmsProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public VtfmsProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new VtfmsFrameDecoder()); @@ -32,7 +35,7 @@ public class VtfmsProtocol extends BaseProtocol { pipeline.addLast(new VtfmsProtocolDecoder(VtfmsProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringDecoder()); diff --git a/src/main/java/org/traccar/protocol/WatchProtocol.java b/src/main/java/org/traccar/protocol/WatchProtocol.java index fe96b3828..600f81328 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocol.java +++ b/src/main/java/org/traccar/protocol/WatchProtocol.java @@ -21,9 +21,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class WatchProtocol extends BaseProtocol { - public WatchProtocol() { + @Inject + public WatchProtocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, @@ -41,7 +44,7 @@ public class WatchProtocol extends BaseProtocol { Command.TYPE_VOICE_MESSAGE, Command.TYPE_SET_TIMEZONE, Command.TYPE_SET_INDICATOR); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WatchFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/WialonProtocol.java b/src/main/java/org/traccar/protocol/WialonProtocol.java index 204bdd341..a744349cd 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocol.java +++ b/src/main/java/org/traccar/protocol/WialonProtocol.java @@ -27,15 +27,18 @@ import org.traccar.model.Command; import java.nio.charset.StandardCharsets; +import javax.inject.Inject; + public class WialonProtocol extends BaseProtocol { - public WialonProtocol() { + @Inject + public WialonProtocol(Config config) { setSupportedDataCommands( Command.TYPE_REBOOT_DEVICE, Command.TYPE_SEND_USSD, Command.TYPE_IDENTIFICATION, Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); @@ -51,7 +54,7 @@ public class WialonProtocol extends BaseProtocol { pipeline.addLast(new WialonProtocolDecoder(WialonProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); diff --git a/src/main/java/org/traccar/protocol/WliProtocol.java b/src/main/java/org/traccar/protocol/WliProtocol.java index aab25abca..f7084e55b 100644 --- a/src/main/java/org/traccar/protocol/WliProtocol.java +++ b/src/main/java/org/traccar/protocol/WliProtocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class WliProtocol extends BaseProtocol { - public WliProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public WliProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WliFrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/WondexProtocol.java b/src/main/java/org/traccar/protocol/WondexProtocol.java index dc3ed3413..5a0401df4 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocol.java +++ b/src/main/java/org/traccar/protocol/WondexProtocol.java @@ -22,9 +22,12 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class WondexProtocol extends BaseProtocol { - public WondexProtocol() { + @Inject + public WondexProtocol(Config config) { setSupportedDataCommands( Command.TYPE_GET_DEVICE_STATUS, Command.TYPE_GET_MODEM_STATUS, @@ -40,7 +43,7 @@ public class WondexProtocol extends BaseProtocol { Command.TYPE_POSITION_SINGLE, Command.TYPE_GET_VERSION, Command.TYPE_IDENTIFICATION); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new WondexFrameDecoder()); @@ -49,7 +52,7 @@ public class WondexProtocol extends BaseProtocol { pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/WristbandProtocol.java b/src/main/java/org/traccar/protocol/WristbandProtocol.java index 38f85f45a..c5d8d4050 100644 --- a/src/main/java/org/traccar/protocol/WristbandProtocol.java +++ b/src/main/java/org/traccar/protocol/WristbandProtocol.java @@ -21,10 +21,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class WristbandProtocol extends BaseProtocol { - public WristbandProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public WristbandProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, 3, 0)); diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index d64190ad8..4630a69e0 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Xexun2Protocol extends BaseProtocol { - public Xexun2Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Xexun2Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xexun2FrameDecoder()); diff --git a/src/main/java/org/traccar/protocol/XexunProtocol.java b/src/main/java/org/traccar/protocol/XexunProtocol.java index 2e6d4393b..5c7329603 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocol.java +++ b/src/main/java/org/traccar/protocol/XexunProtocol.java @@ -25,13 +25,16 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Command; +import javax.inject.Inject; + public class XexunProtocol extends BaseProtocol { - public XexunProtocol() { + @Inject + public XexunProtocol(Config config) { setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { boolean full = config.getBoolean(Keys.PROTOCOL_EXTENDED.withPrefix(getName())); diff --git a/src/main/java/org/traccar/protocol/XirgoProtocol.java b/src/main/java/org/traccar/protocol/XirgoProtocol.java index f986ca3e6..0841d86d5 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocol.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocol.java @@ -24,12 +24,15 @@ import org.traccar.TrackerServer; import org.traccar.config.Config; import org.traccar.model.Command; +import javax.inject.Inject; + public class XirgoProtocol extends BaseProtocol { - public XirgoProtocol() { + @Inject + public XirgoProtocol(Config config) { setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##")); @@ -39,7 +42,7 @@ public class XirgoProtocol extends BaseProtocol { pipeline.addLast(new XirgoProtocolDecoder(XirgoProtocol.this)); } }); - addServer(new TrackerServer(true, getName()) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new StringEncoder()); diff --git a/src/main/java/org/traccar/protocol/Xrb28Protocol.java b/src/main/java/org/traccar/protocol/Xrb28Protocol.java index 53eed5595..65c2a1230 100644 --- a/src/main/java/org/traccar/protocol/Xrb28Protocol.java +++ b/src/main/java/org/traccar/protocol/Xrb28Protocol.java @@ -26,16 +26,19 @@ import org.traccar.model.Command; import java.nio.charset.StandardCharsets; +import javax.inject.Inject; + public class Xrb28Protocol extends BaseProtocol { - public Xrb28Protocol() { + @Inject + public Xrb28Protocol(Config config) { setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM); - addServer(new TrackerServer(false, getName()) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Xt013Protocol.java b/src/main/java/org/traccar/protocol/Xt013Protocol.java index aaed47c89..9e9087609 100644 --- a/src/main/java/org/traccar/protocol/Xt013Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt013Protocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Xt013Protocol extends BaseProtocol { - public Xt013Protocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public Xt013Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); diff --git a/src/main/java/org/traccar/protocol/Xt2400Protocol.java b/src/main/java/org/traccar/protocol/Xt2400Protocol.java index 81567b82c..e200adb9f 100644 --- a/src/main/java/org/traccar/protocol/Xt2400Protocol.java +++ b/src/main/java/org/traccar/protocol/Xt2400Protocol.java @@ -20,10 +20,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class Xt2400Protocol extends BaseProtocol { - public Xt2400Protocol() { - addServer(new TrackerServer(true, getName()) { + @Inject + public Xt2400Protocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xt2400ProtocolDecoder(Xt2400Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/YwtProtocol.java b/src/main/java/org/traccar/protocol/YwtProtocol.java index 6dd8623c9..fb44e2360 100644 --- a/src/main/java/org/traccar/protocol/YwtProtocol.java +++ b/src/main/java/org/traccar/protocol/YwtProtocol.java @@ -23,10 +23,13 @@ import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import javax.inject.Inject; + public class YwtProtocol extends BaseProtocol { - public YwtProtocol() { - addServer(new TrackerServer(false, getName()) { + @Inject + public YwtProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new LineBasedFrameDecoder(1024)); -- cgit v1.2.3 From e665a2c7f4dd925bed116961da48bb018d6f57f7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 14:36:31 -0700 Subject: Remove static injector usages --- src/main/java/org/traccar/BasePipelineFactory.java | 7 +++++-- src/main/java/org/traccar/MainEventHandler.java | 8 +++++--- src/main/java/org/traccar/MainModule.java | 5 ++--- src/main/java/org/traccar/WebDataHandler.java | 9 +++++---- src/main/java/org/traccar/api/resource/DeviceResource.java | 6 +++++- src/main/java/org/traccar/database/MailManager.java | 7 ++++--- src/main/java/org/traccar/session/ConnectionManager.java | 12 ++++++------ 7 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 3eb7011a1..915c3f7ea 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -15,6 +15,7 @@ */ package org.traccar; +import com.google.inject.Injector; import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInboundHandler; @@ -55,11 +56,13 @@ import java.util.Map; public abstract class BasePipelineFactory extends ChannelInitializer { + private final Injector injector; private final TrackerConnector connector; private final String protocol; private int timeout; public BasePipelineFactory(TrackerConnector connector, Config config, String protocol) { + this.injector = Main.getInjector(); this.connector = connector; this.protocol = protocol; timeout = config.getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol)); @@ -76,7 +79,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { private void addHandlers(ChannelPipeline pipeline, Class... handlerClasses) { for (Class handlerClass : handlerClasses) { if (handlerClass != null) { - pipeline.addLast(Main.getInjector().getInstance(handlerClass)); + pipeline.addLast(injector.getInstance(handlerClass)); } } } @@ -111,7 +114,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { addProtocolHandlers(handler -> { if (handler instanceof BaseProtocolDecoder || handler instanceof BaseProtocolEncoder) { - Main.getInjector().injectMembers(handler); + injector.injectMembers(handler); } else { if (handler instanceof ChannelInboundHandler) { handler = new WrapperInboundHandler((ChannelInboundHandler) handler); diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index d2665cbcc..965421d2f 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -55,13 +55,16 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final CacheManager cacheManager; private final Storage storage; private final ConnectionManager connectionManager; + private final StatisticsManager statisticsManager; @Inject public MainEventHandler( - Config config, CacheManager cacheManager, Storage storage, ConnectionManager connectionManager) { + Config config, CacheManager cacheManager, Storage storage, + ConnectionManager connectionManager, StatisticsManager statisticsManager) { this.cacheManager = cacheManager; this.storage = storage; this.connectionManager = connectionManager; + this.statisticsManager = statisticsManager; String connectionlessProtocolList = config.getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split("[, ]"))); @@ -139,8 +142,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { } LOGGER.info(builder.toString()); - Main.getInjector().getInstance(StatisticsManager.class) - .registerMessageStored(position.getDeviceId(), position.getProtocol()); + statisticsManager.registerMessageStored(position.getDeviceId(), position.getProtocol()); } } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 3120118fc..5a5675859 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -111,9 +111,8 @@ public class MainModule extends AbstractModule { } @Provides - public static Client provideClient() { - return ClientBuilder.newClient().register( - (ContextResolver) clazz -> Main.getInjector().getInstance(ObjectMapper.class)); + public static Client provideClient(ObjectMapper objectMapper) { + return ClientBuilder.newClient().register((ContextResolver) clazz -> objectMapper); } @Singleton diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index 192a15bcf..d25c4fd3c 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,6 +63,7 @@ public class WebDataHandler extends BaseDataHandler { private final CacheManager cacheManager; private final ObjectMapper objectMapper; private final Client client; + private final Timer timer; private final String url; private final String header; @@ -78,11 +79,12 @@ public class WebDataHandler extends BaseDataHandler { @Inject public WebDataHandler( - Config config, CacheManager cacheManager, ObjectMapper objectMapper, Client client) { + Config config, CacheManager cacheManager, ObjectMapper objectMapper, Client client, Timer timer) { this.cacheManager = cacheManager; this.objectMapper = objectMapper; this.client = client; + this.timer = timer; this.url = config.getString(Keys.FORWARD_URL); this.header = config.getString(Keys.FORWARD_HEADER); this.json = config.getBoolean(Keys.FORWARD_JSON); @@ -248,8 +250,7 @@ public class WebDataHandler extends BaseDataHandler { } private void schedule() { - Main.getInjector().getInstance(Timer.class).newTimeout( - this, retryDelay * (long) Math.pow(2, retries++), TimeUnit.MILLISECONDS); + timer.newTimeout(this, retryDelay * (long) Math.pow(2, retries++), TimeUnit.MILLISECONDS); } @Override diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 2509c9003..6660752d3 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -28,6 +28,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.PUT; @@ -45,6 +46,9 @@ import java.util.List; @Consumes(MediaType.APPLICATION_JSON) public class DeviceResource extends BaseObjectResource { + @Inject + private CacheManager cacheManager; + public DeviceResource() { super(Device.class); } @@ -122,7 +126,7 @@ public class DeviceResource extends BaseObjectResource { new Columns.Include("positionId"), new Condition.Equals("id", "id"))); - Main.getInjector().getInstance(CacheManager.class).updatePosition(position); + cacheManager.updatePosition(position); } else { throw new IllegalArgumentException(); } diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index 54f617d5f..ac0db2d97 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -18,7 +18,6 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; import org.traccar.config.Config; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; @@ -42,10 +41,12 @@ public final class MailManager { private static final Logger LOGGER = LoggerFactory.getLogger(MailManager.class); private final Config config; + private final StatisticsManager statisticsManager; @Inject - public MailManager(Config config) { + public MailManager(Config config, StatisticsManager statisticsManager) { this.config = config; + this.statisticsManager = statisticsManager; } private static Properties getProperties(PropertiesProvider provider) { @@ -145,7 +146,7 @@ public final class MailManager { } try (Transport transport = session.getTransport()) { - Main.getInjector().getInstance(StatisticsManager.class).registerMail(); + statisticsManager.registerMail(); transport.connect( properties.getProperty("mail.smtp.host"), properties.getProperty("mail.smtp.username"), diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index cead771c9..05c4893fd 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -15,12 +15,12 @@ */ package org.traccar.session; +import com.google.inject.Injector; import io.netty.channel.Channel; import io.netty.util.Timeout; import io.netty.util.Timer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Main; import org.traccar.Protocol; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -64,6 +64,7 @@ public class ConnectionManager { private final Map deviceStates = new ConcurrentHashMap<>(); + private final Injector injector; private final Config config; private final CacheManager cacheManager; private final Storage storage; @@ -75,8 +76,9 @@ public class ConnectionManager { @Inject public ConnectionManager( - Config config, CacheManager cacheManager, Storage storage, + Injector injector, Config config, CacheManager cacheManager, Storage storage, NotificationManager notificationManager, Timer timer) { + this.injector = injector; this.config = config; this.cacheManager = cacheManager; this.storage = storage; @@ -279,15 +281,13 @@ public class ConnectionManager { DeviceState deviceState = getDeviceState(deviceId); Map result = new HashMap<>(); - Map event = Main.getInjector() - .getInstance(MotionEventHandler.class).updateMotionState(deviceState); + Map event = injector.getInstance(MotionEventHandler.class).updateMotionState(deviceState); if (event != null) { result.putAll(event); } double speedLimit = AttributeUtil.lookup(cacheManager, Keys.EVENT_OVERSPEED_LIMIT, deviceId); - event = Main.getInjector().getInstance(OverspeedEventHandler.class) - .updateOverspeedState(deviceState, speedLimit); + event = injector.getInstance(OverspeedEventHandler.class).updateOverspeedState(deviceState, speedLimit); if (event != null) { result.putAll(event); } -- cgit v1.2.3 From 215a0590d3adb91a41eea48e8f7830395be03418 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 15:14:52 -0700 Subject: Make private --- src/main/java/org/traccar/database/NotificationManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 46b58dd75..92f4c818a 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -65,7 +65,7 @@ public class NotificationManager { geocodeOnRequest = config.getBoolean(Keys.GEOCODER_ON_REQUEST); } - public void updateEvent(Event event, Position position) { + private void updateEvent(Event event, Position position) { try { event.setId(storage.addObject(event, new Request(new Columns.Exclude("id")))); } catch (StorageException error) { -- cgit v1.2.3 From bea3f2131a5cd3cd2501bbd30421e402590af86a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 16:02:17 -0700 Subject: Remove unused import --- src/main/java/org/traccar/api/resource/DeviceResource.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 6660752d3..74e133f44 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -15,7 +15,6 @@ */ package org.traccar.api.resource; -import org.traccar.Main; import org.traccar.api.BaseObjectResource; import org.traccar.helper.LogAction; import org.traccar.model.Device; -- cgit v1.2.3 From 440c6069b81bde2a241b5c0829cf951246a386f2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 16:27:43 -0700 Subject: Fix tests --- src/test/java/org/traccar/WebDataHandlerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/traccar/WebDataHandlerTest.java b/src/test/java/org/traccar/WebDataHandlerTest.java index 1e6e1214f..99dbb83fa 100644 --- a/src/test/java/org/traccar/WebDataHandlerTest.java +++ b/src/test/java/org/traccar/WebDataHandlerTest.java @@ -31,7 +31,7 @@ public class WebDataHandlerTest extends ProtocolTest { var cacheManager = mock(CacheManager.class); when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); - WebDataHandler handler = new WebDataHandler(config, cacheManager, null, null); + WebDataHandler handler = new WebDataHandler(config, cacheManager, null, null, null); assertEquals( "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", -- cgit v1.2.3 From 45940f73c57b871711ee9fb41ebeba3c0ca9e9b6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 18 Jun 2022 16:48:15 -0700 Subject: Fix offline device notifications --- .../org/traccar/database/NotificationManager.java | 13 +++++++++++-- .../java/org/traccar/session/ConnectionManager.java | 7 +++++-- .../java/org/traccar/session/cache/CacheManager.java | 19 ++++++++++++++++--- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 92f4c818a..1314a3d0a 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -118,8 +118,17 @@ public class NotificationManager { } public void updateEvents(Map events) { - for (Entry event : events.entrySet()) { - updateEvent(event.getKey(), event.getValue()); + for (Entry entry : events.entrySet()) { + Event event = entry.getKey(); + Position position = entry.getValue(); + try { + cacheManager.addDevice(event.getDeviceId()); + updateEvent(event, position); + } catch (StorageException e) { + throw new RuntimeException(e); + } finally { + cacheManager.removeDevice(event.getDeviceId()); + } } } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 05c4893fd..fe6521d18 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -144,7 +144,10 @@ public class ConnectionManager { endpointSessions.put(device.getUniqueId(), deviceSession); sessionsByEndpoint.put(endpoint, endpointSessions); sessionsByDeviceId.put(device.getId(), deviceSession); - cacheManager.addDevice(device.getId()); + + if (oldSession == null) { + cacheManager.addDevice(device.getId()); + } return deviceSession; } else { @@ -190,8 +193,8 @@ public class ConnectionManager { public void deviceUnknown(long deviceId) { updateDevice(deviceId, Device.STATUS_UNKNOWN, null); DeviceSession deviceSession = sessionsByDeviceId.remove(deviceId); - cacheManager.removeDevice(deviceId); if (deviceSession != null) { + cacheManager.removeDevice(deviceId); Endpoint endpoint = new Endpoint(deviceSession.getChannel(), deviceSession.getRemoteAddress()); sessionsByEndpoint.computeIfPresent(endpoint, (e, sessions) -> { sessions.remove(deviceSession.getUniqueId()); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 87384f746..abc8ca4c9 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -60,6 +60,7 @@ public class CacheManager { private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final Map deviceCache = new HashMap<>(); + private final Map deviceReferences = new HashMap<>(); private final Map, List>> deviceLinks = new HashMap<>(); private final Map devicePositions = new HashMap<>(); @@ -136,9 +137,14 @@ public class CacheManager { public void addDevice(long deviceId) throws StorageException { try { lock.writeLock().lock(); - if (!deviceLinks.containsKey(deviceId)) { + Integer references = deviceReferences.get(deviceId); + if (references != null) { + references += 1; + } else { unsafeAddDevice(deviceId); + references = 1; } + deviceReferences.put(deviceId, references); } finally { lock.writeLock().unlock(); } @@ -147,8 +153,15 @@ public class CacheManager { public void removeDevice(long deviceId) { try { lock.writeLock().lock(); - if (deviceLinks.containsKey(deviceId)) { - unsafeRemoveDevice(deviceId); + Integer references = deviceReferences.get(deviceId); + if (references != null) { + references -= 1; + if (references <= 0) { + unsafeRemoveDevice(deviceId); + deviceReferences.remove(deviceId); + } else { + deviceReferences.put(deviceId, references); + } } } finally { lock.writeLock().unlock(); -- cgit v1.2.3 From 5afb5176c63e97b1a99ef54aa7af09927fb1f3f2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Jun 2022 07:14:23 -0700 Subject: Simplify select statements --- debug.xml | 2 +- src/main/java/org/traccar/storage/DatabaseStorage.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/debug.xml b/debug.xml index 73576b20b..50e70c812 100644 --- a/debug.xml +++ b/debug.xml @@ -12,7 +12,7 @@ true true - false + true org.h2.Driver jdbc:h2:./target/database diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 052f11ad2..eec72b510 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -54,7 +54,11 @@ public class DatabaseStorage extends Storage { @Override public List getObjects(Class clazz, Request request) throws StorageException { StringBuilder query = new StringBuilder("SELECT "); - query.append(formatColumns(request.getColumns(), clazz, "get", c -> c)); + if (request.getColumns() instanceof Columns.All) { + query.append('*'); + } else { + query.append(formatColumns(request.getColumns(), clazz, "get", c -> c)); + } query.append(" FROM ").append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); query.append(formatOrder(request.getOrder())); -- cgit v1.2.3 From afae915a0db4e641e8e93b1d334d62804c83868f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Jun 2022 07:21:51 -0700 Subject: Fix login issue --- src/main/java/org/traccar/database/LoginService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/database/LoginService.java b/src/main/java/org/traccar/database/LoginService.java index a30e443b5..6ed45202a 100644 --- a/src/main/java/org/traccar/database/LoginService.java +++ b/src/main/java/org/traccar/database/LoginService.java @@ -52,7 +52,7 @@ public class LoginService { public User login(String email, String password) throws StorageException { User user = storage.getObject(User.class, new Request( - new Columns.Include("id", "login", "hashedPassword", "salt"), + new Columns.All(), new Condition.Or( new Condition.Equals("email", "email", email.trim()), new Condition.Equals("login", "email")))); -- cgit v1.2.3 From 009e19b44c5becefb0cb84777c2db62bf1d5005e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 20 Jun 2022 14:40:41 -0700 Subject: Remove extra space --- src/main/java/org/traccar/database/LoginService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/traccar/database/LoginService.java b/src/main/java/org/traccar/database/LoginService.java index 6ed45202a..2c541e2aa 100644 --- a/src/main/java/org/traccar/database/LoginService.java +++ b/src/main/java/org/traccar/database/LoginService.java @@ -73,7 +73,6 @@ public class LoginService { return null; } - private void checkUserEnabled(User user) throws SecurityException { if (user == null) { throw new SecurityException("Unknown account"); -- cgit v1.2.3 From f5a9207393463879cfe85e94259ee70d6d5b9980 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Jun 2022 07:02:42 -0700 Subject: Support service admin account --- .../org/traccar/api/resource/SessionResource.java | 2 +- .../org/traccar/api/security/LoginService.java | 94 ++++++++++++++++++++++ .../traccar/api/security/PermissionsService.java | 8 +- .../api/security/SecurityRequestFilter.java | 1 - .../traccar/api/security/ServiceAccountUser.java | 30 +++++++ src/main/java/org/traccar/config/Keys.java | 8 ++ .../java/org/traccar/database/LoginService.java | 88 -------------------- 7 files changed, 139 insertions(+), 92 deletions(-) create mode 100644 src/main/java/org/traccar/api/security/LoginService.java create mode 100644 src/main/java/org/traccar/api/security/ServiceAccountUser.java delete mode 100644 src/main/java/org/traccar/database/LoginService.java diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 70561f997..91052fc6b 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -16,7 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; -import org.traccar.database.LoginService; +import org.traccar.api.security.LoginService; import org.traccar.helper.DataConverter; import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java new file mode 100644 index 000000000..9938cf6dc --- /dev/null +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -0,0 +1,94 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.api.security; + +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.database.LdapProvider; +import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.annotation.Nullable; +import javax.inject.Inject; + +public class LoginService { + + private final Storage storage; + private final LdapProvider ldapProvider; + + private final String serviceAccountToken; + private final boolean forceLdap; + + @Inject + public LoginService(Config config, Storage storage, @Nullable LdapProvider ldapProvider) { + this.storage = storage; + this.ldapProvider = ldapProvider; + serviceAccountToken = config.getString(Keys.WEB_SERVICE_ACCOUNT_TOKEN); + forceLdap = config.getBoolean(Keys.LDAP_FORCE); + } + + public User login(String token) throws StorageException { + if (serviceAccountToken != null && serviceAccountToken.equals(token)) { + return new ServiceAccountUser(); + } + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("token", "token", token))); + if (user != null) { + checkUserEnabled(user); + } + return user; + } + + public User login(String email, String password) throws StorageException { + User user = storage.getObject(User.class, new Request( + new Columns.All(), + new Condition.Or( + new Condition.Equals("email", "email", email.trim()), + new Condition.Equals("login", "email")))); + if (user != null) { + if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) + || !forceLdap && user.isPasswordValid(password)) { + checkUserEnabled(user); + return user; + } + } else { + if (ldapProvider != null && ldapProvider.login(email, password)) { + user = ldapProvider.getUser(email); + user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); + checkUserEnabled(user); + return user; + } + } + return null; + } + + private void checkUserEnabled(User user) throws SecurityException { + if (user == null) { + throw new SecurityException("Unknown account"); + } + if (user.getDisabled()) { + throw new SecurityException("Account is disabled"); + } + if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { + throw new SecurityException("Account has expired"); + } + } + +} diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index ea7a9d572..e5bc52f22 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -58,8 +58,12 @@ public class PermissionsService { public User getUser(long userId) throws StorageException { if (user == null && userId > 0) { - user = storage.getObject( - User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); + if (userId == ServiceAccountUser.ID) { + user = new ServiceAccountUser(); + } else { + user = storage.getObject( + User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); + } } return user; } diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index 3413175c8..eaf5b28c4 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -18,7 +18,6 @@ package org.traccar.api.security; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.api.resource.SessionResource; -import org.traccar.database.LoginService; import org.traccar.database.StatisticsManager; import org.traccar.helper.DataConverter; import org.traccar.model.User; diff --git a/src/main/java/org/traccar/api/security/ServiceAccountUser.java b/src/main/java/org/traccar/api/security/ServiceAccountUser.java new file mode 100644 index 000000000..644142434 --- /dev/null +++ b/src/main/java/org/traccar/api/security/ServiceAccountUser.java @@ -0,0 +1,30 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.api.security; + +import org.traccar.model.User; + +public class ServiceAccountUser extends User { + + public static final long ID = 9000000000000000000L; + + public ServiceAccountUser() { + setId(ID); + setName("Service Account"); + setEmail("none"); + setAdministrator(true); + } +} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index a03e47022..3f52fbd96 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -673,6 +673,14 @@ public final class Keys { "web.debug", List.of(KeyType.CONFIG)); + /** + * A token to login as a virtual admin account. Can be used to restore access in case of issues with regular admin + * login. For example, if password is lost and can't be restored. + */ + public static final ConfigKey WEB_SERVICE_ACCOUNT_TOKEN = new StringConfigKey( + "web.serviceAccountToken", + List.of(KeyType.CONFIG)); + /** * Cross-origin resource sharing origin header value. */ diff --git a/src/main/java/org/traccar/database/LoginService.java b/src/main/java/org/traccar/database/LoginService.java deleted file mode 100644 index 2c541e2aa..000000000 --- a/src/main/java/org/traccar/database/LoginService.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2022 Anton Tananaev (anton@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.database; - -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.model.User; -import org.traccar.storage.Storage; -import org.traccar.storage.StorageException; -import org.traccar.storage.query.Columns; -import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Request; - -import javax.annotation.Nullable; -import javax.inject.Inject; - -public class LoginService { - - private final Storage storage; - private final LdapProvider ldapProvider; - - private final boolean forceLdap; - - @Inject - public LoginService(Config config, Storage storage, @Nullable LdapProvider ldapProvider) { - this.storage = storage; - this.ldapProvider = ldapProvider; - forceLdap = config.getBoolean(Keys.LDAP_FORCE); - } - - public User login(String token) throws StorageException { - User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("token", "token", token))); - if (user != null) { - checkUserEnabled(user); - } - return user; - } - - public User login(String email, String password) throws StorageException { - User user = storage.getObject(User.class, new Request( - new Columns.All(), - new Condition.Or( - new Condition.Equals("email", "email", email.trim()), - new Condition.Equals("login", "email")))); - if (user != null) { - if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) - || !forceLdap && user.isPasswordValid(password)) { - checkUserEnabled(user); - return user; - } - } else { - if (ldapProvider != null && ldapProvider.login(email, password)) { - user = ldapProvider.getUser(email); - user.setId(storage.addObject(user, new Request(new Columns.Exclude("id")))); - checkUserEnabled(user); - return user; - } - } - return null; - } - - private void checkUserEnabled(User user) throws SecurityException { - if (user == null) { - throw new SecurityException("Unknown account"); - } - if (user.getDisabled()) { - throw new SecurityException("Account is disabled"); - } - if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { - throw new SecurityException("Account has expired"); - } - } - -} -- cgit v1.2.3 From cc9eca495f93b8ffaee0fe5b10b62f1f3dfbf945 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Jun 2022 07:22:14 -0700 Subject: Return storage info --- .../java/org/traccar/api/resource/ServerResource.java | 6 ++++++ src/main/java/org/traccar/helper/Log.java | 18 ++++++++++++++++++ src/main/java/org/traccar/model/Server.java | 12 ++++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index b66f5a931..2ef99c578 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -18,8 +18,10 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; import org.traccar.database.MailManager; import org.traccar.geocoder.Geocoder; +import org.traccar.helper.Log; import org.traccar.helper.LogAction; import org.traccar.model.Server; +import org.traccar.model.User; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -60,6 +62,10 @@ public class ServerResource extends BaseResource { public Server get() throws StorageException { Server server = storage.getObject(Server.class, new Request(new Columns.All())); server.setEmailEnabled(mailManager.getEmailEnabled()); + User user = permissionsService.getUser(getUserId()); + if (user != null && user.getAdministrator()) { + server.setStorageSpace(Log.getStorageSpace()); + } return server; } diff --git a/src/main/java/org/traccar/helper/Log.java b/src/main/java/org/traccar/helper/Log.java index 8c67f9ddc..e1b201f9f 100644 --- a/src/main/java/org/traccar/helper/Log.java +++ b/src/main/java/org/traccar/helper/Log.java @@ -28,6 +28,10 @@ import java.io.StringWriter; import java.io.Writer; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.nio.file.FileStore; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.ConsoleHandler; @@ -269,4 +273,18 @@ public final class Log { return s.toString(); } + public static long[] getStorageSpace() { + long usable = 0; + long total = 0; + for (Path root : FileSystems.getDefault().getRootDirectories()) { + try { + FileStore store = Files.getFileStore(root); + usable += store.getUsableSpace(); + total += store.getTotalSpace(); + } catch (IOException ignored) { + } + } + return new long[]{usable, total}; + } + } diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index ee7f7069a..648be2991 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -214,4 +214,16 @@ public class Server extends ExtendedModel implements UserRestrictions { return emailEnabled; } + private long[] storageSpace; + + @QueryIgnore + public long[] getStorageSpace() { + return storageSpace; + } + + @QueryIgnore + public void setStorageSpace(long[] storageSpace) { + this.storageSpace = storageSpace; + } + } -- cgit v1.2.3 From 1271b2e7a772c8458b567d7f424d5a38365b5d75 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Jun 2022 08:35:59 -0700 Subject: Login as another user --- .../java/org/traccar/api/resource/SessionResource.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 91052fc6b..8eabdc63c 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -22,6 +22,9 @@ import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; import org.traccar.model.User; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.annotation.security.PermitAll; import javax.inject.Inject; @@ -33,6 +36,7 @@ import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; @@ -107,6 +111,17 @@ public class SessionResource extends BaseResource { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } + @Path("{id}") + @GET + public User get(@PathParam("id") long userId) throws StorageException { + permissionsService.checkAdmin(getUserId()); + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", userId))); + request.getSession().setAttribute(USER_ID_KEY, user.getId()); + LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); + return user; + } + @PermitAll @POST public User add( -- cgit v1.2.3 From 6a608f109ab587803092374591d1ec22e8f40fb7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Jun 2022 08:43:50 -0700 Subject: Support token API authentication --- .../java/org/traccar/api/security/SecurityRequestFilter.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index eaf5b28c4..ada7bf997 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -43,6 +43,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; public static final String BASIC_REALM = "Basic realm=\"api\""; + public static final String BEARER_PREFIX = "Bearer "; public static final String X_REQUESTED_WITH = "X-Requested-With"; public static final String XML_HTTP_REQUEST = "XMLHttpRequest"; @@ -82,8 +83,13 @@ public class SecurityRequestFilter implements ContainerRequestFilter { if (authHeader != null) { try { - String[] auth = decodeBasicAuth(authHeader); - User user = loginService.login(auth[0], auth[1]); + User user; + if (authHeader.startsWith(BEARER_PREFIX)) { + user = loginService.login(authHeader.substring(BEARER_PREFIX.length())); + } else { + String[] auth = decodeBasicAuth(authHeader); + user = loginService.login(auth[0], auth[1]); + } if (user != null) { statisticsManager.registerRequest(user.getId()); securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); -- cgit v1.2.3 From d24edbc439a96b38442be1fbbfaccf65f0dd1923 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Jun 2022 08:58:34 -0700 Subject: Fix accumulator update --- src/main/java/org/traccar/MainEventHandler.java | 2 -- src/main/java/org/traccar/api/resource/DeviceResource.java | 12 +++++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 965421d2f..06791c540 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -89,8 +89,6 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { new Condition.Equals("id", "id"))); cacheManager.updatePosition(position); - cacheManager.getObject(Device.class, position.getDeviceId()).setPositionId(position.getId()); - connectionManager.updatePosition(position); } } catch (StorageException error) { diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 74e133f44..ff682d1d1 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -21,6 +21,7 @@ import org.traccar.model.Device; import org.traccar.model.DeviceAccumulators; import org.traccar.model.Position; import org.traccar.model.User; +import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -48,6 +49,9 @@ public class DeviceResource extends BaseObjectResource { @Inject private CacheManager cacheManager; + @Inject + private ConnectionManager connectionManager; + public DeviceResource() { super(Device.class); } @@ -125,7 +129,13 @@ public class DeviceResource extends BaseObjectResource { new Columns.Include("positionId"), new Condition.Equals("id", "id"))); - cacheManager.updatePosition(position); + try { + cacheManager.addDevice(position.getDeviceId()); + cacheManager.updatePosition(position); + connectionManager.updatePosition(position); + } finally { + cacheManager.removeDevice(position.getDeviceId()); + } } else { throw new IllegalArgumentException(); } -- cgit v1.2.3 From bf504bdda752dfbde1a81ece03805d14a4bd117c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 23 Jun 2022 16:29:25 -0700 Subject: Decode ST300UEX serial data --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 4 +++- src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java | 4 ++++ src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 44ba1da38..67a82a688 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -375,7 +375,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } } else if (attribute.startsWith("GTSL")) { position.set(Position.KEY_DRIVER_UNIQUE_ID, attribute.split("\\|")[4]); - } else { + } else if (attribute.contains("=")) { String[] pair = attribute.split("="); if (pair.length >= 2) { String value = pair[1].trim(); @@ -398,6 +398,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { break; } } + } else { + position.set("serial", attribute); } remaining -= attribute.length() + 1; } diff --git a/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java index 96fed314c..6d0351a8e 100644 --- a/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechFrameDecoderTest.java @@ -10,6 +10,10 @@ public class SuntechFrameDecoderTest extends ProtocolTest { var decoder = inject(new SuntechFrameDecoder()); + verifyFrame( + binary("53543330305545583b3531313639393339383b34353b3331353b32303232303632333b31383a32343a35383b3661313332393b2d32392e3735343934373b2d3035372e3038353838353b3030302e3030303b3030302e30303b31303b313b37323b302e30303b3030303030303b31323b0201100110011090011001100110011001100110fe3b39303b3030303030303b332e393b313b30303030303030303030303030303b30"), + decoder.decode(null, null, binary("53543330305545583b3531313639393339383b34353b3331353b32303232303632333b31383a32343a35383b3661313332393b2d32392e3735343934373b2d3035372e3038353838353b3030302e3030303b3030302e30303b31303b313b37323b302e30303b3030303030303b31323b0201100110011090011001100110011001100110fe3b39303b3030303030303b332e393b313b30303030303030303030303030303b300d"))); + verifyFrame( binary("81004e05200013383fffff3401000301130a0512080400000000000000000000000047f9d5846a06810072225214010100020300a8002604c1000004b000000470000025a100000000000025c4000000a6"), decoder.decode(null, null, binary("81004e05200013383fffff3401000301130a0512080400000000000000000000000047f9d5846a06810072225214010100020300a8002604c1000004b000000470000025a100000000000025c4000000a6"))); diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 7fed55454..71f71ce99 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -92,6 +92,13 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, buffer( "BSA;0820012345;001FFF;82;1.0.0;1;20191203;17:00:51;+32.691615;-117.297160;1;-55;68:11:6A:FD:1A:A7;6AA5;1DE8")); + verifyAttributes(decoder, binary( + "53543330305545583b3531313639393339383b34353b3331353b32303232303632333b31383a32343a35383b3661313332393b2d32392e3735343934373b2d3035372e3038353838353b3030302e3030303b3030302e30303b31303b313b37323b302e30303b3030303030303b31323b0201100110011090011001100110011001100110fe3b39303b3030303030303b332e393b313b30303030303030303030303030303b30")); + + verifyAttribute(decoder, buffer( + "ST300UEX;100850000;01;010;20081017;07:41:56;2F100;+37.478519;+126.886819;000.012;000.00;9;1;0;15.30;001100;25;Welcome to Suntech World!;12;0;4.5;1"), + "serial", "Welcome to Suntech World!"); + verifyAttribute(decoder, buffer( "ST300UEX;511331307;45;311;20210420;12:41:01;12361;-01.280825;-047.931773;000.000;000.00;16;1;0;12.54;000000;23;GTSL|6|1|0|9255143|2|;6F;000276;0.0;1;00000000000000;0"), Position.KEY_DRIVER_UNIQUE_ID, "9255143"); -- cgit v1.2.3 From c60743cfab4e31214207da5dab44fc4426d53764 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 24 Jun 2022 08:06:17 -0700 Subject: Check if resources loaded --- src/main/java/org/traccar/web/WebServer.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 6c8a798b4..68eee78e7 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -40,6 +40,8 @@ import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerI import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; import org.traccar.api.CorsResponseFilter; import org.traccar.api.DateParameterConverterProvider; @@ -67,6 +69,8 @@ import java.util.EnumSet; public class WebServer implements LifecycleObject { + private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); + private final Injector injector; private final Config config; private final Server server; @@ -180,6 +184,9 @@ public class WebServer implements LifecycleObject { CorsResponseFilter.class, ResourceErrorHandler.class); resourceConfig.packages(ServerResource.class.getPackage().getName()); + if (resourceConfig.getClasses().stream().filter(ServerResource.class::equals).findAny().isEmpty()) { + LOGGER.warn("Failed to load API resources"); + } servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } -- cgit v1.2.3 From 5a732a26c85785a9b801583f2fff0ce47314aa03 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Jun 2022 07:54:39 -0700 Subject: Add throttling filter --- build.gradle | 1 + src/main/java/org/traccar/config/Keys.java | 7 +++ .../java/org/traccar/web/ThrottlingFilter.java | 53 ++++++++++++++++++++++ src/main/java/org/traccar/web/WebModule.java | 1 + 4 files changed, 62 insertions(+) create mode 100644 src/main/java/org/traccar/web/ThrottlingFilter.java diff --git a/build.gradle b/build.gradle index 8c196043a..8ce916432 100644 --- a/build.gradle +++ b/build.gradle @@ -54,6 +54,7 @@ dependencies { implementation "org.glassfish:javax.json:1.1.4" implementation "org.eclipse.jetty:jetty-server:$jettyVersion" implementation "org.eclipse.jetty:jetty-servlet:$jettyVersion" + implementation "org.eclipse.jetty:jetty-servlets:$jettyVersion" implementation "org.eclipse.jetty:jetty-webapp:$jettyVersion" implementation "org.eclipse.jetty:jetty-jndi:$jettyVersion" implementation "org.eclipse.jetty:jetty-proxy:$jettyVersion" diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 3f52fbd96..8e11b4013 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -628,6 +628,13 @@ public final class Keys { "web.port", List.of(KeyType.CONFIG)); + /** + * Maximum API requests per second. Above this limit requests and delayed and throttled. + */ + public static final ConfigKey WEB_MAX_REQUESTS_PER_SECOND = new IntegerConfigKey( + "web.maxRequestsPerSec", + List.of(KeyType.CONFIG)); + /** * Sanitize all strings returned via API. This is needed to fix XSS issues in the old web interface. New React-based * interface doesn't require this. diff --git a/src/main/java/org/traccar/web/ThrottlingFilter.java b/src/main/java/org/traccar/web/ThrottlingFilter.java new file mode 100644 index 000000000..054af652f --- /dev/null +++ b/src/main/java/org/traccar/web/ThrottlingFilter.java @@ -0,0 +1,53 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.web; + +import org.eclipse.jetty.servlets.DoSFilter; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +@Singleton +public class ThrottlingFilter extends DoSFilter { + + @Inject + private Config config; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + super.init(filterConfig); + if (config.hasKey(Keys.WEB_MAX_REQUESTS_PER_SECOND)) { + setMaxRequestsPerSec(config.getInteger(Keys.WEB_MAX_REQUESTS_PER_SECOND)); + } + } + + @Override + protected String extractUserId(ServletRequest request) { + HttpSession session = ((HttpServletRequest) request).getSession(false); + if (session != null) { + var userId = session.getAttribute("userId"); + return userId != null ? userId.toString() : null; + } + return null; + } +} diff --git a/src/main/java/org/traccar/web/WebModule.java b/src/main/java/org/traccar/web/WebModule.java index 6c133ff74..0722c5d1e 100644 --- a/src/main/java/org/traccar/web/WebModule.java +++ b/src/main/java/org/traccar/web/WebModule.java @@ -23,6 +23,7 @@ public class WebModule extends ServletModule { @Override protected void configureServlets() { + filter("/api/*").through(ThrottlingFilter.class); filter("/api/media/*").through(MediaFilter.class); serve("/api/socket").with(AsyncSocketServlet.class); } -- cgit v1.2.3 From c53d98c668af9c79767e22964f05c7bf7dc866f2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Jun 2022 13:33:35 -0700 Subject: Integrate broadcast service --- src/main/java/org/traccar/MainEventHandler.java | 8 +- src/main/java/org/traccar/MainModule.java | 7 +- .../java/org/traccar/api/BaseObjectResource.java | 8 +- .../org/traccar/api/resource/DeviceResource.java | 8 +- .../traccar/api/resource/PermissionsResource.java | 22 ++- .../org/traccar/broadcast/BroadcastInterface.java | 41 +++++ .../org/traccar/broadcast/BroadcastMessage.java | 43 +++++- .../org/traccar/broadcast/BroadcastService.java | 80 +--------- .../java/org/traccar/broadcast/DeviceStatus.java | 52 ------- .../broadcast/MulticastBroadcastService.java | 170 +++++++++++++++++++++ .../traccar/broadcast/NullBroadcastService.java | 31 ++++ src/main/java/org/traccar/model/Permission.java | 8 +- .../org/traccar/notificators/NotificatorWeb.java | 8 +- .../org/traccar/session/ConnectionManager.java | 13 +- .../org/traccar/session/cache/CacheManager.java | 37 +++-- 15 files changed, 374 insertions(+), 162 deletions(-) create mode 100644 src/main/java/org/traccar/broadcast/BroadcastInterface.java delete mode 100644 src/main/java/org/traccar/broadcast/DeviceStatus.java create mode 100644 src/main/java/org/traccar/broadcast/MulticastBroadcastService.java create mode 100644 src/main/java/org/traccar/broadcast/NullBroadcastService.java diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 06791c540..0a8c69b54 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -23,6 +23,7 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; @@ -56,15 +57,17 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Storage storage; private final ConnectionManager connectionManager; private final StatisticsManager statisticsManager; + private final BroadcastService broadcastService; @Inject public MainEventHandler( - Config config, CacheManager cacheManager, Storage storage, - ConnectionManager connectionManager, StatisticsManager statisticsManager) { + Config config, CacheManager cacheManager, Storage storage, ConnectionManager connectionManager, + StatisticsManager statisticsManager, BroadcastService broadcastService) { this.cacheManager = cacheManager; this.storage = storage; this.connectionManager = connectionManager; this.statisticsManager = statisticsManager; + this.broadcastService = broadcastService; String connectionlessProtocolList = config.getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split("[, ]"))); @@ -90,6 +93,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { cacheManager.updatePosition(position); connectionManager.updatePosition(position); + broadcastService.updatePosition(position); } } catch (StorageException error) { LOGGER.warn("Failed to update device", error); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 5a5675859..f60d41d62 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -29,6 +29,8 @@ import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.log.NullLogChute; import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; +import org.traccar.broadcast.MulticastBroadcastService; +import org.traccar.broadcast.NullBroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; @@ -278,13 +280,14 @@ public class MainModule extends AbstractModule { return null; } + @Singleton @Provides public static BroadcastService provideBroadcastService( Config config, ObjectMapper objectMapper) throws IOException { if (config.hasKey(Keys.BROADCAST_ADDRESS)) { - return new BroadcastService(config, objectMapper); + return new MulticastBroadcastService(config, objectMapper); } - return null; + return new NullBroadcastService(); } @Provides diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 35ff04bf3..403021c6c 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -16,6 +16,7 @@ */ package org.traccar.api; +import org.traccar.broadcast.BroadcastService; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Group; @@ -41,6 +42,9 @@ public abstract class BaseObjectResource extends BaseResour @Inject private CacheManager cacheManager; + @Inject + private BroadcastService broadcastService; + protected final Class baseClass; public BaseObjectResource(Class baseClass) { @@ -67,7 +71,8 @@ public abstract class BaseObjectResource extends BaseResour entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); - cacheManager.invalidate(User.class, getUserId(), baseClass, entity.getId()); + cacheManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); + broadcastService.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); return Response.ok(entity).build(); @@ -94,6 +99,7 @@ public abstract class BaseObjectResource extends BaseResour new Columns.Exclude("id"), new Condition.Equals("id", "id"))); cacheManager.updateOrInvalidate(entity); + broadcastService.invalidateObject(entity.getClass(), entity.getId()); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index ff682d1d1..2b673a108 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -16,6 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseObjectResource; +import org.traccar.broadcast.BroadcastService; import org.traccar.helper.LogAction; import org.traccar.model.Device; import org.traccar.model.DeviceAccumulators; @@ -37,6 +38,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.io.IOException; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -52,6 +54,9 @@ public class DeviceResource extends BaseObjectResource { @Inject private ConnectionManager connectionManager; + @Inject + private BroadcastService broadcastService; + public DeviceResource() { super(Device.class); } @@ -105,7 +110,7 @@ public class DeviceResource extends BaseObjectResource { @Path("{id}/accumulators") @PUT - public Response updateAccumulators(DeviceAccumulators entity) throws StorageException { + public Response updateAccumulators(DeviceAccumulators entity) throws StorageException, IOException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkManager(getUserId()); permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); @@ -133,6 +138,7 @@ public class DeviceResource extends BaseObjectResource { cacheManager.addDevice(position.getDeviceId()); cacheManager.updatePosition(position); connectionManager.updatePosition(position); + broadcastService.updatePosition(position); } finally { cacheManager.removeDevice(position.getDeviceId()); } diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 7174a3eff..5ca865c31 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; +import org.traccar.broadcast.BroadcastService; import org.traccar.helper.LogAction; import org.traccar.model.Permission; import org.traccar.model.UserRestrictions; @@ -45,6 +46,9 @@ public class PermissionsResource extends BaseResource { @Inject private CacheManager cacheManager; + @Inject + private BroadcastService broadcastService; + private void checkPermission(Permission permission) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); @@ -71,9 +75,14 @@ public class PermissionsResource extends BaseResource { Permission permission = new Permission(entity); checkPermission(permission); storage.addPermission(permission); - cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), + cacheManager.invalidatePermission( + permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); - LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), + broadcastService.invalidatePermission( + permission.getOwnerClass(), permission.getOwnerId(), + permission.getPropertyClass(), permission.getPropertyId()); + LogAction.link(getUserId(), + permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } return Response.noContent().build(); @@ -93,9 +102,14 @@ public class PermissionsResource extends BaseResource { Permission permission = new Permission(entity); checkPermission(permission); storage.removePermission(permission); - cacheManager.invalidate(permission.getOwnerClass(), permission.getOwnerId(), + cacheManager.invalidatePermission( + permission.getOwnerClass(), permission.getOwnerId(), + permission.getPropertyClass(), permission.getPropertyId()); + broadcastService.invalidatePermission( + permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); - LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), + LogAction.unlink(getUserId(), + permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); } return Response.noContent().build(); diff --git a/src/main/java/org/traccar/broadcast/BroadcastInterface.java b/src/main/java/org/traccar/broadcast/BroadcastInterface.java new file mode 100644 index 000000000..d5b49f213 --- /dev/null +++ b/src/main/java/org/traccar/broadcast/BroadcastInterface.java @@ -0,0 +1,41 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.broadcast; + +import org.traccar.model.BaseModel; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Position; + +public interface BroadcastInterface { + + default void updateDevice(Device device) { + } + + default void updatePosition(Position position) { + } + + default void updateEvent(long userId, Event event) { + } + + default void invalidateObject(Class clazz, long id) { + } + + default void invalidatePermission( + Class clazz1, long id1, + Class clazz2, long id2) { + } +} diff --git a/src/main/java/org/traccar/broadcast/BroadcastMessage.java b/src/main/java/org/traccar/broadcast/BroadcastMessage.java index 6b103f373..3e22be7e0 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastMessage.java +++ b/src/main/java/org/traccar/broadcast/BroadcastMessage.java @@ -15,18 +15,22 @@ */ package org.traccar.broadcast; +import org.traccar.model.Device; +import org.traccar.model.Event; import org.traccar.model.Position; +import java.util.Map; + public class BroadcastMessage { - private DeviceStatus deviceStatus; + private Device device; - public DeviceStatus getDeviceStatus() { - return deviceStatus; + public Device getDevice() { + return device; } - public void setDeviceStatus(DeviceStatus deviceStatus) { - this.deviceStatus = deviceStatus; + public void setDevice(Device device) { + this.device = device; } private Position position; @@ -39,4 +43,33 @@ public class BroadcastMessage { this.position = position; } + private Long userId; + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + private Event event; + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + + private Map changes; + + public Map getChanges() { + return changes; + } + + public void setChanges(Map changes) { + this.changes = changes; + } } diff --git a/src/main/java/org/traccar/broadcast/BroadcastService.java b/src/main/java/org/traccar/broadcast/BroadcastService.java index 26e38400b..8a2e4bafc 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastService.java +++ b/src/main/java/org/traccar/broadcast/BroadcastService.java @@ -15,84 +15,8 @@ */ package org.traccar.broadcast; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; -import org.traccar.config.Config; -import org.traccar.config.Keys; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.MulticastSocket; -import java.nio.charset.StandardCharsets; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class BroadcastService implements LifecycleObject { - - private static final Logger LOGGER = LoggerFactory.getLogger(BroadcastService.class); - - private final ObjectMapper objectMapper; - - private final InetAddress address; - private final int port; - - private DatagramSocket publisherSocket; - - private final ExecutorService service = Executors.newSingleThreadExecutor(); - private final byte[] receiverBuffer = new byte[4096]; - - public BroadcastService(Config config, ObjectMapper objectMapper) throws IOException { - this.objectMapper = objectMapper; - address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); - port = config.getInteger(Keys.BROADCAST_PORT); - } - - public void sendMessage(BroadcastMessage message) throws IOException { - byte[] buffer = objectMapper.writeValueAsString(message).getBytes(StandardCharsets.UTF_8); - DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port); - publisherSocket.send(packet); - } - - private void handleMessage(BroadcastMessage message) { - if (message.getDeviceStatus() != null) { - LOGGER.info("Broadcast received device {}", message.getDeviceStatus().getDeviceId()); - } else if (message.getPosition() != null) { - LOGGER.info("Broadcast received position {}", message.getPosition().getDeviceId()); - } - } - - @Override - public void start() throws IOException { - service.submit(receiver); - publisherSocket = new DatagramSocket(); - } - - @Override - public void stop() { - publisherSocket.close(); - service.shutdown(); - } - - private final Runnable receiver = new Runnable() { - @Override - public void run() { - try (MulticastSocket socket = new MulticastSocket(port)) { - socket.joinGroup(address); - while (!service.isShutdown()) { - DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); - socket.receive(packet); - String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); - handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); - } - socket.leaveGroup(address); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }; +public interface BroadcastService extends LifecycleObject, BroadcastInterface { + void registerListener(BroadcastInterface listener); } diff --git a/src/main/java/org/traccar/broadcast/DeviceStatus.java b/src/main/java/org/traccar/broadcast/DeviceStatus.java deleted file mode 100644 index 4f0143319..000000000 --- a/src/main/java/org/traccar/broadcast/DeviceStatus.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2022 Anton Tananaev (anton@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.broadcast; - -import java.util.Date; - -public class DeviceStatus { - - private long deviceId; - - public long getDeviceId() { - return deviceId; - } - - public void setDeviceId(long deviceId) { - this.deviceId = deviceId; - } - - private String status; - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - private Date lastUpdate; - - public Date getLastUpdate() { - return this.lastUpdate; - } - - public void setLastUpdate(Date lastUpdate) { - this.lastUpdate = lastUpdate; - } - -} diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java new file mode 100644 index 000000000..0525fa742 --- /dev/null +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -0,0 +1,170 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.broadcast; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.BaseModel; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Permission; +import org.traccar.model.Position; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class MulticastBroadcastService implements BroadcastService { + + private static final Logger LOGGER = LoggerFactory.getLogger(MulticastBroadcastService.class); + + private final ObjectMapper objectMapper; + + private final InetAddress address; + private final int port; + + private DatagramSocket publisherSocket; + + private final ExecutorService service = Executors.newSingleThreadExecutor(); + private final byte[] receiverBuffer = new byte[4096]; + + private final Set listeners = new HashSet<>(); + + public MulticastBroadcastService(Config config, ObjectMapper objectMapper) throws IOException { + this.objectMapper = objectMapper; + address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); + port = config.getInteger(Keys.BROADCAST_PORT); + } + + @Override + public void registerListener(BroadcastInterface listener) { + listeners.add(listener); + } + + @Override + public void updateDevice(Device device) { + BroadcastMessage message = new BroadcastMessage(); + message.setDevice(device); + sendMessage(message); + } + + @Override + public void updatePosition(Position position) { + BroadcastMessage message = new BroadcastMessage(); + message.setPosition(position); + sendMessage(message); + } + + @Override + public void updateEvent(long userId, Event event) { + BroadcastMessage message = new BroadcastMessage(); + message.setUserId(userId); + message.setEvent(event); + sendMessage(message); + } + + @Override + public void invalidateObject(Class clazz, long id) { + BroadcastMessage message = new BroadcastMessage(); + message.setChanges(Map.of(Permission.getKey(clazz), id)); + sendMessage(message); + } + + @Override + public void invalidatePermission( + Class clazz1, long id1, + Class clazz2, long id2) { + BroadcastMessage message = new BroadcastMessage(); + message.setChanges(Map.of(Permission.getKey(clazz1), id1, Permission.getKey(clazz2), id2)); + sendMessage(message); + } + + private void sendMessage(BroadcastMessage message) { + try { + byte[] buffer = objectMapper.writeValueAsString(message).getBytes(StandardCharsets.UTF_8); + DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port); + publisherSocket.send(packet); + } catch (IOException e) { + LOGGER.warn("Broadcast failed", e); + } + } + + private void handleMessage(BroadcastMessage message) { + if (message.getDevice() != null) { + listeners.forEach(listener -> listener.updateDevice(message.getDevice())); + } else if (message.getPosition() != null) { + listeners.forEach(listener -> listener.updatePosition(message.getPosition())); + } else if (message.getUserId() != null && message.getEvent() != null) { + listeners.forEach(listener -> listener.updateEvent(message.getUserId(), message.getEvent())); + } else if (message.getChanges() != null) { + var iterator = message.getChanges().entrySet().iterator(); + if (iterator.hasNext()) { + var first = iterator.next(); + if (iterator.hasNext()) { + var second = iterator.next(); + listeners.forEach(listener -> listener.invalidatePermission( + Permission.getKeyClass(first.getKey()), first.getValue(), + Permission.getKeyClass(second.getKey()), second.getValue())); + } else { + listeners.forEach(listener -> listener.invalidateObject( + Permission.getKeyClass(first.getKey()), first.getValue())); + } + } + } + } + + @Override + public void start() throws IOException { + service.submit(receiver); + publisherSocket = new DatagramSocket(); + } + + @Override + public void stop() { + publisherSocket.close(); + service.shutdown(); + } + + private final Runnable receiver = new Runnable() { + @SuppressWarnings("deprecation") + @Override + public void run() { + try (MulticastSocket socket = new MulticastSocket(port)) { + socket.joinGroup(address); + while (!service.isShutdown()) { + DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); + socket.receive(packet); + String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); + handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); + } + socket.leaveGroup(address); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }; +} diff --git a/src/main/java/org/traccar/broadcast/NullBroadcastService.java b/src/main/java/org/traccar/broadcast/NullBroadcastService.java new file mode 100644 index 000000000..3f41299db --- /dev/null +++ b/src/main/java/org/traccar/broadcast/NullBroadcastService.java @@ -0,0 +1,31 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.broadcast; + +public class NullBroadcastService implements BroadcastService { + + @Override + public void registerListener(BroadcastInterface listener) { + } + + @Override + public void start() throws Exception { + } + + @Override + public void stop() throws Exception { + } +} diff --git a/src/main/java/org/traccar/model/Permission.java b/src/main/java/org/traccar/model/Permission.java index 41dfa43e4..0b2f0584f 100644 --- a/src/main/java/org/traccar/model/Permission.java +++ b/src/main/java/org/traccar/model/Permission.java @@ -54,10 +54,10 @@ public class Permission { this.data = data; var iterator = data.entrySet().iterator(); var owner = iterator.next(); - ownerClass = CLASSES.get(owner.getKey().substring(0, owner.getKey().length() - 2)); + ownerClass = getKeyClass(owner.getKey()); ownerId = owner.getValue(); var property = iterator.next(); - propertyClass = CLASSES.get(property.getKey().substring(0, property.getKey().length() - 2)); + propertyClass = getKeyClass(property.getKey()); propertyId = property.getValue(); } @@ -73,6 +73,10 @@ public class Permission { data.put(getKey(propertyClass), propertyId); } + public static Class getKeyClass(String key) { + return CLASSES.get(key.substring(0, key.length() - 2)); + } + public static String getKey(Class clazz) { return Introspector.decapitalize(clazz.getSimpleName()) + "Id"; } diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 3d899584d..efbbf24cc 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -16,6 +16,7 @@ */ package org.traccar.notificators; +import org.traccar.broadcast.BroadcastService; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; @@ -27,11 +28,15 @@ import javax.inject.Inject; public final class NotificatorWeb implements Notificator { private final ConnectionManager connectionManager; + private final BroadcastService broadcastService; private final NotificationFormatter notificationFormatter; @Inject - public NotificatorWeb(ConnectionManager connectionManager, NotificationFormatter notificationFormatter) { + public NotificatorWeb( + ConnectionManager connectionManager, BroadcastService broadcastService, + NotificationFormatter notificationFormatter) { this.connectionManager = connectionManager; + this.broadcastService = broadcastService; this.notificationFormatter = notificationFormatter; } @@ -52,6 +57,7 @@ public final class NotificatorWeb implements Notificator { copy.set("message", message.getBody()); connectionManager.updateEvent(user.getId(), copy); + broadcastService.updateEvent(user.getId(), copy); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index fe6521d18..74427c08b 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -22,6 +22,8 @@ import io.netty.util.Timer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Protocol; +import org.traccar.broadcast.BroadcastInterface; +import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.NotificationManager; @@ -52,7 +54,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @Singleton -public class ConnectionManager { +public class ConnectionManager implements BroadcastInterface { private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); @@ -70,6 +72,7 @@ public class ConnectionManager { private final Storage storage; private final NotificationManager notificationManager; private final Timer timer; + private final BroadcastService broadcastService; private final Map> listeners = new ConcurrentHashMap<>(); private final Map timeouts = new ConcurrentHashMap<>(); @@ -77,15 +80,17 @@ public class ConnectionManager { @Inject public ConnectionManager( Injector injector, Config config, CacheManager cacheManager, Storage storage, - NotificationManager notificationManager, Timer timer) { + NotificationManager notificationManager, Timer timer, BroadcastService broadcastService) { this.injector = injector; this.config = config; this.cacheManager = cacheManager; this.storage = storage; this.notificationManager = notificationManager; this.timer = timer; + this.broadcastService = broadcastService; deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT) * 1000; updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); + broadcastService.registerListener(this); } public DeviceSession getDeviceSession(long deviceId) { @@ -270,6 +275,7 @@ public class ConnectionManager { } updateDevice(device); + broadcastService.updateDevice(device); } public DeviceState getDeviceState(long deviceId) { @@ -306,6 +312,7 @@ public class ConnectionManager { } } + @Override public synchronized void updateDevice(Device device) { for (User user : cacheManager.getDeviceObjects(device.getId(), User.class)) { if (listeners.containsKey(user.getId())) { @@ -316,6 +323,7 @@ public class ConnectionManager { } } + @Override public synchronized void updatePosition(Position position) { long deviceId = position.getDeviceId(); for (User user : cacheManager.getDeviceObjects(deviceId, User.class)) { @@ -327,6 +335,7 @@ public class ConnectionManager { } } + @Override public synchronized void updateEvent(long userId, Event event) { if (listeners.containsKey(userId)) { for (UpdateListener listener : listeners.get(userId)) { diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index abc8ca4c9..d2ada7d43 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -15,6 +15,8 @@ */ package org.traccar.session.cache; +import org.traccar.broadcast.BroadcastInterface; +import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.helper.model.GeofenceUtil; import org.traccar.model.Attribute; @@ -49,7 +51,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; @Singleton -public class CacheManager { +public class CacheManager implements BroadcastInterface { private static final Collection> CLASSES = Arrays.asList( Attribute.class, Driver.class, Geofence.class, Maintenance.class, Notification.class); @@ -68,9 +70,10 @@ public class CacheManager { private final Map> notificationUsers = new HashMap<>(); @Inject - public CacheManager(Config config, Storage storage) throws StorageException { + public CacheManager(Config config, Storage storage, BroadcastService broadcastService) throws StorageException { this.config = config; this.storage = storage; + broadcastService.registerListener(this); invalidateServer(); invalidateUsers(); } @@ -179,13 +182,18 @@ public class CacheManager { } } - public void updateOrInvalidate(Class clazz, long id) throws StorageException { - var object = storage.getObject(clazz, new Request( - new Columns.All(), new Condition.Equals("id", "id", id))); - if (object != null) { - updateOrInvalidate(object); - } else { - invalidate(clazz, id); + @Override + public void invalidateObject(Class clazz, long id) { + try { + var object = storage.getObject(clazz, new Request( + new Columns.All(), new Condition.Equals("id", "id", id))); + if (object != null) { + updateOrInvalidate(object); + } else { + invalidate(clazz, id); + } + } catch (StorageException e) { + throw new RuntimeException(e); } } @@ -219,10 +227,15 @@ public class CacheManager { invalidate(new CacheKey(clazz, id)); } - public void invalidate( + @Override + public void invalidatePermission( Class clazz1, long id1, - Class clazz2, long id2) throws StorageException { - invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); + Class clazz2, long id2) { + try { + invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); + } catch (StorageException e) { + throw new RuntimeException(e); + } } private void invalidateServer() throws StorageException { -- cgit v1.2.3 From 2fcffc5b55f59310d289a21d1ebc2ee6bf15bcd5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Jun 2022 14:17:00 -0700 Subject: Fix connection users issue --- src/main/java/org/traccar/MainEventHandler.java | 4 +- src/main/java/org/traccar/api/AsyncSocket.java | 7 +-- .../org/traccar/api/resource/DeviceResource.java | 4 +- .../org/traccar/broadcast/BroadcastInterface.java | 6 +- .../broadcast/MulticastBroadcastService.java | 12 ++-- .../handler/events/GeofenceEventHandler.java | 2 +- .../org/traccar/notificators/NotificatorWeb.java | 4 +- .../org/traccar/session/ConnectionManager.java | 66 +++++++++++++++------- 8 files changed, 65 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 0a8c69b54..e2cad15c6 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -92,8 +92,8 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { new Condition.Equals("id", "id"))); cacheManager.updatePosition(position); - connectionManager.updatePosition(position); - broadcastService.updatePosition(position); + connectionManager.updatePosition(true, position); + broadcastService.updatePosition(true, position); } } catch (StorageException error) { LOGGER.warn("Failed to update device", error); diff --git a/src/main/java/org/traccar/api/AsyncSocket.java b/src/main/java/org/traccar/api/AsyncSocket.java index 40aa68e88..5fc4b4412 100644 --- a/src/main/java/org/traccar/api/AsyncSocket.java +++ b/src/main/java/org/traccar/api/AsyncSocket.java @@ -58,15 +58,14 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U public void onWebSocketConnect(Session session) { super.onWebSocketConnect(session); - Map> data = new HashMap<>(); try { + Map> data = new HashMap<>(); data.put(KEY_POSITIONS, PositionUtil.getLatestPositions(storage, userId)); + sendData(data); + connectionManager.addListener(userId, this); } catch (StorageException e) { throw new RuntimeException(e); } - sendData(data); - - connectionManager.addListener(userId, this); } @Override diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 2b673a108..e205f2d28 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -137,8 +137,8 @@ public class DeviceResource extends BaseObjectResource { try { cacheManager.addDevice(position.getDeviceId()); cacheManager.updatePosition(position); - connectionManager.updatePosition(position); - broadcastService.updatePosition(position); + connectionManager.updatePosition(true, position); + broadcastService.updatePosition(true, position); } finally { cacheManager.removeDevice(position.getDeviceId()); } diff --git a/src/main/java/org/traccar/broadcast/BroadcastInterface.java b/src/main/java/org/traccar/broadcast/BroadcastInterface.java index d5b49f213..69e610dc6 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastInterface.java +++ b/src/main/java/org/traccar/broadcast/BroadcastInterface.java @@ -22,13 +22,13 @@ import org.traccar.model.Position; public interface BroadcastInterface { - default void updateDevice(Device device) { + default void updateDevice(boolean local, Device device) { } - default void updatePosition(Position position) { + default void updatePosition(boolean local, Position position) { } - default void updateEvent(long userId, Event event) { + default void updateEvent(boolean local, long userId, Event event) { } default void invalidateObject(Class clazz, long id) { diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index 0525fa742..ac0fcbd86 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -66,21 +66,21 @@ public class MulticastBroadcastService implements BroadcastService { } @Override - public void updateDevice(Device device) { + public void updateDevice(boolean local, Device device) { BroadcastMessage message = new BroadcastMessage(); message.setDevice(device); sendMessage(message); } @Override - public void updatePosition(Position position) { + public void updatePosition(boolean local, Position position) { BroadcastMessage message = new BroadcastMessage(); message.setPosition(position); sendMessage(message); } @Override - public void updateEvent(long userId, Event event) { + public void updateEvent(boolean local, long userId, Event event) { BroadcastMessage message = new BroadcastMessage(); message.setUserId(userId); message.setEvent(event); @@ -115,11 +115,11 @@ public class MulticastBroadcastService implements BroadcastService { private void handleMessage(BroadcastMessage message) { if (message.getDevice() != null) { - listeners.forEach(listener -> listener.updateDevice(message.getDevice())); + listeners.forEach(listener -> listener.updateDevice(false, message.getDevice())); } else if (message.getPosition() != null) { - listeners.forEach(listener -> listener.updatePosition(message.getPosition())); + listeners.forEach(listener -> listener.updatePosition(false, message.getPosition())); } else if (message.getUserId() != null && message.getEvent() != null) { - listeners.forEach(listener -> listener.updateEvent(message.getUserId(), message.getEvent())); + listeners.forEach(listener -> listener.updateEvent(false, message.getUserId(), message.getEvent())); } else if (message.getChanges() != null) { var iterator = message.getChanges().entrySet().iterator(); if (iterator.hasNext()) { diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 0a924cfc3..ca3fc3f89 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -68,7 +68,7 @@ public class GeofenceEventHandler extends BaseEventHandler { device.setGeofenceIds(currentGeofences); if (!oldGeofences.isEmpty() || !newGeofences.isEmpty()) { - connectionManager.updateDevice(device); + connectionManager.updateDevice(true, device); } Map events = new HashMap<>(); diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index efbbf24cc..061018ba9 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -56,8 +56,8 @@ public final class NotificatorWeb implements Notificator { var message = notificationFormatter.formatMessage(user, event, position, "short"); copy.set("message", message.getBody()); - connectionManager.updateEvent(user.getId(), copy); - broadcastService.updateEvent(user.getId(), copy); + connectionManager.updateEvent(true, user.getId(), copy); + broadcastService.updateEvent(true, user.getId(), copy); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 74427c08b..0e0ea1eb8 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -30,6 +30,7 @@ import org.traccar.database.NotificationManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; import org.traccar.helper.model.AttributeUtil; +import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; @@ -45,6 +46,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -52,6 +54,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; @Singleton public class ConnectionManager implements BroadcastInterface { @@ -74,7 +77,10 @@ public class ConnectionManager implements BroadcastInterface { private final Timer timer; private final BroadcastService broadcastService; - private final Map> listeners = new ConcurrentHashMap<>(); + private final Map> listeners = new HashMap<>(); + private final Map> userDevices = new HashMap<>(); + private final Map> deviceUsers = new HashMap<>(); + private final Map timeouts = new ConcurrentHashMap<>(); @Inject @@ -197,6 +203,10 @@ public class ConnectionManager implements BroadcastInterface { public void deviceUnknown(long deviceId) { updateDevice(deviceId, Device.STATUS_UNKNOWN, null); + removeDeviceSession(deviceId); + } + + private void removeDeviceSession(long deviceId) { DeviceSession deviceSession = sessionsByDeviceId.remove(deviceId); if (deviceSession != null) { cacheManager.removeDevice(deviceId); @@ -274,8 +284,8 @@ public class ConnectionManager implements BroadcastInterface { LOGGER.warn("Update device status error", e); } - updateDevice(device); - broadcastService.updateDevice(device); + updateDevice(true, device); + broadcastService.updateDevice(true, device); } public DeviceState getDeviceState(long deviceId) { @@ -313,10 +323,14 @@ public class ConnectionManager implements BroadcastInterface { } @Override - public synchronized void updateDevice(Device device) { - for (User user : cacheManager.getDeviceObjects(device.getId(), User.class)) { - if (listeners.containsKey(user.getId())) { - for (UpdateListener listener : listeners.get(user.getId())) { + public synchronized void updateDevice(boolean local, Device device) { + if (!local && Device.STATUS_ONLINE.equals(device.getStatus())) { + timeouts.remove(device.getId()); + removeDeviceSession(device.getId()); + } + for (long userId : deviceUsers.getOrDefault(device.getId(), Collections.emptySet())) { + if (listeners.containsKey(userId)) { + for (UpdateListener listener : listeners.get(userId)) { listener.onUpdateDevice(device); } } @@ -324,11 +338,10 @@ public class ConnectionManager implements BroadcastInterface { } @Override - public synchronized void updatePosition(Position position) { - long deviceId = position.getDeviceId(); - for (User user : cacheManager.getDeviceObjects(deviceId, User.class)) { - if (listeners.containsKey(user.getId())) { - for (UpdateListener listener : listeners.get(user.getId())) { + public synchronized void updatePosition(boolean local, Position position) { + for (long userId : deviceUsers.getOrDefault(position.getDeviceId(), Collections.emptySet())) { + if (listeners.containsKey(userId)) { + for (UpdateListener listener : listeners.get(userId)) { listener.onUpdatePosition(position); } } @@ -336,7 +349,7 @@ public class ConnectionManager implements BroadcastInterface { } @Override - public synchronized void updateEvent(long userId, Event event) { + public synchronized void updateEvent(boolean local, long userId, Event event) { if (listeners.containsKey(userId)) { for (UpdateListener listener : listeners.get(userId)) { listener.onUpdateEvent(event); @@ -351,18 +364,31 @@ public class ConnectionManager implements BroadcastInterface { void onUpdateEvent(Event event); } - public synchronized void addListener(long userId, UpdateListener listener) { - if (!listeners.containsKey(userId)) { - listeners.put(userId, new HashSet<>()); + public synchronized void addListener(long userId, UpdateListener listener) throws StorageException { + var set = listeners.get(userId); + if (set == null) { + set = new HashSet<>(); + listeners.put(userId, set); + + var devices = storage.getObjects(Device.class, new Request( + new Columns.Include("id"), new Condition.Permission(User.class, userId, Device.class))); + userDevices.put(userId, devices.stream().map(BaseModel::getId).collect(Collectors.toUnmodifiableSet())); + devices.forEach(device -> deviceUsers.computeIfAbsent(device.getId(), id -> new HashSet<>()).add(userId)); } - listeners.get(userId).add(listener); + set.add(listener); } public synchronized void removeListener(long userId, UpdateListener listener) { - if (!listeners.containsKey(userId)) { - listeners.put(userId, new HashSet<>()); + var set = listeners.get(userId); + set.remove(listener); + if (set.isEmpty()) { + listeners.remove(userId); + + userDevices.remove(userId).forEach(deviceId -> deviceUsers.computeIfPresent(deviceId, (x, userIds) -> { + userIds.remove(userId); + return userIds.isEmpty() ? null : userIds; + })); } - listeners.get(userId).remove(listener); } } -- cgit v1.2.3 From bf0173eb4bac4ab86b43f101eb013051bfc40817 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 25 Jun 2022 14:24:08 -0700 Subject: Simplify broadcast calls --- src/main/java/org/traccar/MainEventHandler.java | 1 - src/main/java/org/traccar/api/BaseObjectResource.java | 6 ------ src/main/java/org/traccar/api/resource/DeviceResource.java | 1 - .../java/org/traccar/api/resource/PermissionsResource.java | 10 ---------- src/main/java/org/traccar/notificators/NotificatorWeb.java | 1 - src/main/java/org/traccar/session/ConnectionManager.java | 11 +++++++++-- src/main/java/org/traccar/session/cache/CacheManager.java | 8 +++++++- 7 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index e2cad15c6..981888577 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -93,7 +93,6 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { cacheManager.updatePosition(position); connectionManager.updatePosition(true, position); - broadcastService.updatePosition(true, position); } } catch (StorageException error) { LOGGER.warn("Failed to update device", error); diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 403021c6c..489360619 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -16,7 +16,6 @@ */ package org.traccar.api; -import org.traccar.broadcast.BroadcastService; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Group; @@ -42,9 +41,6 @@ public abstract class BaseObjectResource extends BaseResour @Inject private CacheManager cacheManager; - @Inject - private BroadcastService broadcastService; - protected final Class baseClass; public BaseObjectResource(Class baseClass) { @@ -72,7 +68,6 @@ public abstract class BaseObjectResource extends BaseResour LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); cacheManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); - broadcastService.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); return Response.ok(entity).build(); @@ -99,7 +94,6 @@ public abstract class BaseObjectResource extends BaseResour new Columns.Exclude("id"), new Condition.Equals("id", "id"))); cacheManager.updateOrInvalidate(entity); - broadcastService.invalidateObject(entity.getClass(), entity.getId()); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index e205f2d28..8791a82f9 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -138,7 +138,6 @@ public class DeviceResource extends BaseObjectResource { cacheManager.addDevice(position.getDeviceId()); cacheManager.updatePosition(position); connectionManager.updatePosition(true, position); - broadcastService.updatePosition(true, position); } finally { cacheManager.removeDevice(position.getDeviceId()); } diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 5ca865c31..44fc897ac 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -17,7 +17,6 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; -import org.traccar.broadcast.BroadcastService; import org.traccar.helper.LogAction; import org.traccar.model.Permission; import org.traccar.model.UserRestrictions; @@ -46,9 +45,6 @@ public class PermissionsResource extends BaseResource { @Inject private CacheManager cacheManager; - @Inject - private BroadcastService broadcastService; - private void checkPermission(Permission permission) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkPermission(permission.getOwnerClass(), getUserId(), permission.getOwnerId()); @@ -78,9 +74,6 @@ public class PermissionsResource extends BaseResource { cacheManager.invalidatePermission( permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); - broadcastService.invalidatePermission( - permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId()); LogAction.link(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); @@ -105,9 +98,6 @@ public class PermissionsResource extends BaseResource { cacheManager.invalidatePermission( permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); - broadcastService.invalidatePermission( - permission.getOwnerClass(), permission.getOwnerId(), - permission.getPropertyClass(), permission.getPropertyId()); LogAction.unlink(getUserId(), permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index 061018ba9..f495042a5 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -57,7 +57,6 @@ public final class NotificatorWeb implements Notificator { copy.set("message", message.getBody()); connectionManager.updateEvent(true, user.getId(), copy); - broadcastService.updateEvent(true, user.getId(), copy); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 0e0ea1eb8..c2f602c11 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -285,7 +285,6 @@ public class ConnectionManager implements BroadcastInterface { } updateDevice(true, device); - broadcastService.updateDevice(true, device); } public DeviceState getDeviceState(long deviceId) { @@ -324,7 +323,9 @@ public class ConnectionManager implements BroadcastInterface { @Override public synchronized void updateDevice(boolean local, Device device) { - if (!local && Device.STATUS_ONLINE.equals(device.getStatus())) { + if (local) { + broadcastService.updateDevice(true, device); + } else if (Device.STATUS_ONLINE.equals(device.getStatus())) { timeouts.remove(device.getId()); removeDeviceSession(device.getId()); } @@ -339,6 +340,9 @@ public class ConnectionManager implements BroadcastInterface { @Override public synchronized void updatePosition(boolean local, Position position) { + if (local) { + broadcastService.updatePosition(true, position); + } for (long userId : deviceUsers.getOrDefault(position.getDeviceId(), Collections.emptySet())) { if (listeners.containsKey(userId)) { for (UpdateListener listener : listeners.get(userId)) { @@ -350,6 +354,9 @@ public class ConnectionManager implements BroadcastInterface { @Override public synchronized void updateEvent(boolean local, long userId, Event event) { + if (local) { + broadcastService.updateEvent(true, userId, event); + } if (listeners.containsKey(userId)) { for (UpdateListener listener : listeners.get(userId)) { listener.onUpdateEvent(event); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index d2ada7d43..bc5fc357f 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -58,6 +58,7 @@ public class CacheManager implements BroadcastInterface { private final Config config; private final Storage storage; + private final BroadcastService broadcastService; private final ReadWriteLock lock = new ReentrantReadWriteLock(); @@ -73,9 +74,10 @@ public class CacheManager implements BroadcastInterface { public CacheManager(Config config, Storage storage, BroadcastService broadcastService) throws StorageException { this.config = config; this.storage = storage; - broadcastService.registerListener(this); + this.broadcastService = broadcastService; invalidateServer(); invalidateUsers(); + broadcastService.registerListener(this); } public Config getConfig() { @@ -198,6 +200,8 @@ public class CacheManager implements BroadcastInterface { } public void updateOrInvalidate(T object) throws StorageException { + broadcastService.invalidateObject(object.getClass(), object.getId()); + boolean invalidate = false; var before = getObject(object.getClass(), object.getId()); if (before == null) { @@ -231,6 +235,8 @@ public class CacheManager implements BroadcastInterface { public void invalidatePermission( Class clazz1, long id1, Class clazz2, long id2) { + broadcastService.invalidatePermission(clazz1, id1, clazz2, id2); + try { invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); } catch (StorageException e) { -- cgit v1.2.3 From 2812c02d18ccf3ad9fadab921516cd5ff8755668 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Jun 2022 16:51:51 -0700 Subject: Missing SMTP config error --- src/main/java/org/traccar/database/MailManager.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index ac0db2d97..0c868e1fc 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -16,8 +16,6 @@ */ package org.traccar.database; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; @@ -38,8 +36,6 @@ import java.util.Properties; public final class MailManager { - private static final Logger LOGGER = LoggerFactory.getLogger(MailManager.class); - private final Config config; private final StatisticsManager statisticsManager; @@ -115,8 +111,7 @@ public final class MailManager { properties = getProperties(new PropertiesProvider(config)); } if (!properties.containsKey("mail.smtp.host")) { - LOGGER.warn("No SMTP configuration found"); - return; + throw new RuntimeException("No SMTP configuration found"); } Session session = Session.getInstance(properties); -- cgit v1.2.3 From 08d634d984c1388c3919d7c6645506b202307dac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Jun 2022 18:43:15 -0700 Subject: Temporary disable group lookup --- src/main/java/org/traccar/helper/model/AttributeUtil.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java index 58b922d95..b438f97dc 100644 --- a/src/main/java/org/traccar/helper/model/AttributeUtil.java +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -19,7 +19,6 @@ import org.traccar.config.ConfigKey; import org.traccar.config.KeyType; import org.traccar.config.Keys; import org.traccar.model.Device; -import org.traccar.model.Group; import org.traccar.session.cache.CacheManager; public final class AttributeUtil { @@ -31,13 +30,6 @@ public final class AttributeUtil { public static T lookup(CacheManager cacheManager, ConfigKey key, long deviceId) { Device device = cacheManager.getObject(Device.class, deviceId); Object result = device.getAttributes().get(key.getKey()); - long groupId = device.getGroupId(); - while (result == null && groupId > 0) { - Group group = cacheManager.getObject(Group.class, groupId); - if (group != null) { - result = group.getAttributes().get(key.getKey()); - } - } if (result == null && key.hasType(KeyType.SERVER)) { result = cacheManager.getServer().getAttributes().get(key.getKey()); } -- cgit v1.2.3 From 3c48c66cf55705274ff482cf3deefee11196ddfe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Jun 2022 07:19:24 -0700 Subject: Fix user registration --- src/main/java/org/traccar/api/resource/UserResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 20fce9e32..1bb399437 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -72,8 +72,8 @@ public class UserResource extends BaseObjectResource { @PermitAll @POST public Response add(User entity) throws StorageException { - User currentUser = permissionsService.getUser(getUserId()); - if (permissionsService.notAdmin(getUserId())) { + User currentUser = getUserId() > 0 ? permissionsService.getUser(getUserId()) : null; + if (currentUser == null || !currentUser.getAdministrator()) { permissionsService.checkUserUpdate(getUserId(), new User(), entity); if (currentUser != null && currentUser.getUserLimit() != 0) { int userLimit = currentUser.getUserLimit(); -- cgit v1.2.3 From 9e07a009a3da41cd3cdd21809e9588e1ed133d6f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Jun 2022 07:39:33 -0700 Subject: Fix device name in reports --- .../org/traccar/reports/StopsReportProvider.java | 10 ++++---- .../org/traccar/reports/SummaryReportProvider.java | 20 ++++++++-------- .../org/traccar/reports/TripsReportProvider.java | 15 ++++++------ .../org/traccar/reports/common/ReportUtils.java | 27 ++++++++-------------- 4 files changed, 32 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index 6e4cd74d6..ba61ef6a1 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -55,10 +55,10 @@ public class StopsReportProvider { this.storage = storage; } - private Collection detectStops(long deviceId, Date from, Date to) throws StorageException { + private Collection detectStops(Device device, Date from, Date to) throws StorageException { boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); - return reportUtils.detectTripsAndStops( - PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, StopReportItem.class); + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); + return reportUtils.detectTripsAndStops(device, positions, ignoreOdometer, StopReportItem.class); } public Collection getObjects( @@ -68,7 +68,7 @@ public class StopsReportProvider { ArrayList result = new ArrayList<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { - result.addAll(detectStops(device.getId(), from, to)); + result.addAll(detectStops(device, from, to)); } return result; } @@ -81,7 +81,7 @@ public class StopsReportProvider { ArrayList devicesStops = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { - Collection stops = detectStops(device.getId(), from, to); + Collection stops = detectStops(device, from, to); DeviceReportSection deviceStops = new DeviceReportSection(); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 26d79c899..02033b9e5 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -58,11 +58,10 @@ public class SummaryReportProvider { this.storage = storage; } - private SummaryReportItem calculateSummaryResult( - long deviceId, Collection positions) throws StorageException { + private SummaryReportItem calculateSummaryResult(Device device, Collection positions) { SummaryReportItem result = new SummaryReportItem(); - result.setDeviceId(deviceId); - result.setDeviceName(reportUtils.getDevice(deviceId).getName()); + result.setDeviceId(device.getId()); + result.setDeviceName(device.getName()); if (positions != null && !positions.isEmpty()) { Position firstPosition = null; Position previousPosition = null; @@ -119,9 +118,9 @@ public class SummaryReportProvider { } private Collection calculateSummaryResults( - long userId, long deviceId, Date from, Date to, boolean daily) throws StorageException { + long userId, Device device, Date from, Date to, boolean daily) throws StorageException { - var positions = PositionUtil.getPositions(storage, deviceId, from, to); + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); var results = new ArrayList(); if (daily && !positions.isEmpty()) { int startIndex = 0; @@ -129,14 +128,14 @@ public class SummaryReportProvider { for (int i = 0; i < positions.size(); i++) { int currentDay = getDay(userId, positions.get(i).getFixTime()); if (currentDay != startDay) { - results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, i))); + results.add(calculateSummaryResult(device, positions.subList(startIndex, i))); startIndex = i; startDay = currentDay; } } - results.add(calculateSummaryResult(deviceId, positions.subList(startIndex, positions.size()))); + results.add(calculateSummaryResult(device, positions.subList(startIndex, positions.size()))); } else { - results.add(calculateSummaryResult(deviceId, positions)); + results.add(calculateSummaryResult(device, positions)); } return results; @@ -149,8 +148,7 @@ public class SummaryReportProvider { ArrayList result = new ArrayList<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { - Collection deviceResults = - calculateSummaryResults(userId, device.getId(), from, to, daily); + Collection deviceResults = calculateSummaryResults(userId, device, from, to, daily); for (SummaryReportItem summaryReport : deviceResults) { if (summaryReport.getStartTime() != null && summaryReport.getEndTime() != null) { result.add(summaryReport); diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 7d10879b7..2d9bcdfbf 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -55,19 +55,20 @@ public class TripsReportProvider { this.storage = storage; } - private Collection detectTrips(long deviceId, Date from, Date to) throws StorageException { + private Collection detectTrips(Device device, Date from, Date to) throws StorageException { boolean ignoreOdometer = config.getBoolean(Keys.REPORT_IGNORE_ODOMETER); - return reportUtils.detectTripsAndStops( - PositionUtil.getPositions(storage, deviceId, from, to), ignoreOdometer, TripReportItem.class); + var positions = PositionUtil.getPositions(storage, device.getId(), from, to); + return reportUtils.detectTripsAndStops(device, positions, ignoreOdometer, TripReportItem.class); } - public Collection getObjects(long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws StorageException { + public Collection getObjects( + long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws StorageException { reportUtils.checkPeriodLimit(from, to); ArrayList result = new ArrayList<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { - result.addAll(detectTrips(device.getId(), from, to)); + result.addAll(detectTrips(device, from, to)); } return result; } @@ -80,7 +81,7 @@ public class TripsReportProvider { ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { - Collection trips = detectTrips(device.getId(), from, to); + Collection trips = detectTrips(device, from, to); DeviceReportSection deviceTrips = new DeviceReportSection(); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index f5f2cd3df..cd6b6ffd5 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -99,12 +99,6 @@ public class ReportUtils { new Condition.Permission(User.class, userId, clazz)))); } - public Device getDevice(long deviceId) throws StorageException { - return storage.getObject(Device.class, new Request( - new Columns.Include("id"), - new Condition.Equals("id", "id", deviceId))); - } - public void checkPeriodLimit(Date from, Date to) { long limit = config.getLong(Keys.REPORT_PERIOD_LIMIT) * 1000; if (limit > 0 && to.getTime() - from.getTime() > limit) { @@ -211,7 +205,7 @@ public class ReportUtils { } private TripReportItem calculateTrip( - ArrayList positions, int startIndex, int endIndex, + Device device, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) throws StorageException { Position startTrip = positions.get(startIndex); @@ -230,7 +224,7 @@ public class ReportUtils { long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); trip.setDeviceId(deviceId); - trip.setDeviceName(getDevice(deviceId).getName()); + trip.setDeviceName(device.getName()); trip.setStartPositionId(startTrip.getId()); trip.setStartLat(startTrip.getLatitude()); @@ -277,8 +271,7 @@ public class ReportUtils { } private StopReportItem calculateStop( - ArrayList positions, int startIndex, int endIndex, - boolean ignoreOdometer) throws StorageException { + Device device, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer) { Position startStop = positions.get(startIndex); Position endStop = positions.get(endIndex); @@ -287,7 +280,7 @@ public class ReportUtils { long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); - stop.setDeviceName(getDevice(deviceId).getName()); + stop.setDeviceName(device.getName()); stop.setPositionId(startStop.getId()); stop.setLatitude(startStop.getLatitude()); @@ -326,13 +319,13 @@ public class ReportUtils { @SuppressWarnings("unchecked") private T calculateTripOrStop( - ArrayList positions, int startIndex, int endIndex, + Device device, ArrayList positions, int startIndex, int endIndex, boolean ignoreOdometer, Class reportClass) throws StorageException { if (reportClass.equals(TripReportItem.class)) { - return (T) calculateTrip(positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateTrip(device, positions, startIndex, endIndex, ignoreOdometer); } else { - return (T) calculateStop(positions, startIndex, endIndex, ignoreOdometer); + return (T) calculateStop(device, positions, startIndex, endIndex, ignoreOdometer); } } @@ -357,7 +350,7 @@ public class ReportUtils { } public Collection detectTripsAndStops( - Collection positionCollection, boolean ignoreOdometer, + Device device, Collection positionCollection, boolean ignoreOdometer, Class reportClass) throws StorageException { Collection result = new ArrayList<>(); @@ -392,14 +385,14 @@ public class ReportUtils { if (startEventIndex != -1 && startNoEventIndex != -1 && event != null && trips != deviceState.getMotionState()) { result.add(calculateTripOrStop( - positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); + device, positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); startEventIndex = -1; } } if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { int endIndex = startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1; result.add(calculateTripOrStop( - positions, startEventIndex, endIndex, ignoreOdometer, reportClass)); + device, positions, startEventIndex, endIndex, ignoreOdometer, reportClass)); } } -- cgit v1.2.3 From ef644e5185b3109b0da30972a0b5c56768c69957 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Jun 2022 07:44:26 -0700 Subject: Fix tests --- .../java/org/traccar/reports/ReportUtilsTest.java | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index dfb2ef05c..b73ae7cc0 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -105,7 +105,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(mock(Device.class), data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -119,7 +119,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -160,7 +160,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -174,7 +174,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); + trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -188,7 +188,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -231,7 +231,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -245,7 +245,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -282,7 +282,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -311,7 +311,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -340,7 +340,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -369,7 +369,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); + Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -394,7 +394,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(data, false, TripReportItem.class); + Collection trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -408,7 +408,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(data, false, StopReportItem.class); + Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From a487c1efa5dff2a7644ee7f2874967f4bb867b6a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Jun 2022 08:13:03 -0700 Subject: Fix new device updates --- src/main/java/org/traccar/api/BaseObjectResource.java | 5 +++++ src/main/java/org/traccar/session/ConnectionManager.java | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 489360619..d10843917 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -21,6 +21,7 @@ import org.traccar.model.BaseModel; import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.User; +import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -41,6 +42,9 @@ public abstract class BaseObjectResource extends BaseResour @Inject private CacheManager cacheManager; + @Inject + private ConnectionManager connectionManager; + protected final Class baseClass; public BaseObjectResource(Class baseClass) { @@ -68,6 +72,7 @@ public abstract class BaseObjectResource extends BaseResour LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); cacheManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); + connectionManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); return Response.ok(entity).build(); diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index c2f602c11..27d6184c2 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -364,6 +364,18 @@ public class ConnectionManager implements BroadcastInterface { } } + @Override + public synchronized void invalidatePermission( + Class clazz1, long id1, + Class clazz2, long id2) { + if (clazz1.equals(User.class) && clazz2.equals(Device.class)) { + if (listeners.containsKey(id1)) { + userDevices.get(id1).add(id2); + deviceUsers.put(id2, Set.of(id1)); + } + } + } + public interface UpdateListener { void onKeepalive(); void onUpdateDevice(Device device); @@ -379,7 +391,7 @@ public class ConnectionManager implements BroadcastInterface { var devices = storage.getObjects(Device.class, new Request( new Columns.Include("id"), new Condition.Permission(User.class, userId, Device.class))); - userDevices.put(userId, devices.stream().map(BaseModel::getId).collect(Collectors.toUnmodifiableSet())); + userDevices.put(userId, devices.stream().map(BaseModel::getId).collect(Collectors.toSet())); devices.forEach(device -> deviceUsers.computeIfAbsent(device.getId(), id -> new HashSet<>()).add(userId)); } set.add(listener); -- cgit v1.2.3 From 9345f8e086105ba30e9e9cf87b3fc5b0740d68e8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Jun 2022 10:47:42 -0700 Subject: Fix device creation issue --- src/main/java/org/traccar/api/security/PermissionsService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index e5bc52f22..a3e7a182f 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -102,8 +102,9 @@ public class PermissionsService { if (getServer().getReadonly() || getUser(userId).getReadonly()) { denied = true; } else if (clazz.equals(Device.class)) { - denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly(); - if (addition) { + denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly() + || addition && getUser(userId).getDeviceLimit() == 0; + if (addition && getUser(userId).getDeviceLimit() > 0) { int deviceCount = storage.getObjects(Device.class, new Request( new Columns.Include("id"), new Condition.Permission(User.class, userId, Device.class))).size(); -- cgit v1.2.3 From 7899f1ffbb0e00243d2b4cf72ffe9bc59bb920bc Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Wed, 29 Jun 2022 09:02:15 +0200 Subject: time advance moved to inner block added a check for 0 mac address on wifi networks. --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index 35fdc3ca5..a71c5606d 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -142,8 +142,8 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { Network network = new Network(); int cellCount = Integer.parseInt(values[index++]); - index += 1; // timing advance if (cellCount > 0) { + index += 1; // timing advance int mcc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; int mnc = !values[index].isEmpty() ? Integer.parseInt(values[index++]) : 0; @@ -164,8 +164,11 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < wifiCount; i++) { index += 1; // wifi name - network.addWifiAccessPoint(WifiAccessPoint.from( - values[index++], Integer.parseInt(values[index++]))); + String macAddress = values[index++]; + String rssi = values[index++]; + if (!macAddress.isEmpty() && !macAddress.equals("0") && !rssi.isEmpty()) { + network.addWifiAccessPoint(WifiAccessPoint.from(macAddress, Integer.parseInt(rssi))); + } } } -- cgit v1.2.3 From 8032eb77ae55a4814c523131ad1aaba9a7556056 Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Wed, 29 Jun 2022 09:02:59 +0200 Subject: test assertion for mac address with zero value --- src/test/java/org/traccar/ProtocolTest.java | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/traccar/ProtocolTest.java b/src/test/java/org/traccar/ProtocolTest.java index 353593c29..3e27bbe28 100644 --- a/src/test/java/org/traccar/ProtocolTest.java +++ b/src/test/java/org/traccar/ProtocolTest.java @@ -14,6 +14,7 @@ import org.traccar.helper.DataConverter; import org.traccar.model.CellTower; import org.traccar.model.Command; import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; import java.nio.charset.StandardCharsets; import java.text.DateFormat; @@ -310,12 +311,20 @@ public class ProtocolTest extends BaseTest { assertTrue(attributes.get(Position.KEY_RESULT) instanceof String); } - if (position.getNetwork() != null && position.getNetwork().getCellTowers() != null) { - for (CellTower cellTower : position.getNetwork().getCellTowers()) { - checkInteger(cellTower.getMobileCountryCode(), 0, 999); - checkInteger(cellTower.getMobileNetworkCode(), 0, 999); - checkInteger(cellTower.getLocationAreaCode(), 1, 65535); - checkInteger(cellTower.getCellId(), 0, 268435455); + if (position.getNetwork() != null) { + if (position.getNetwork().getCellTowers() != null) { + for (CellTower cellTower : position.getNetwork().getCellTowers()) { + checkInteger(cellTower.getMobileCountryCode(), 0, 999); + checkInteger(cellTower.getMobileNetworkCode(), 0, 999); + checkInteger(cellTower.getLocationAreaCode(), 1, 65535); + checkInteger(cellTower.getCellId(), 0, 268435455); + } + } + + if (position.getNetwork().getWifiAccessPoints() != null) { + for (WifiAccessPoint wifiAccessPoint : position.getNetwork().getWifiAccessPoints()) { + assertTrue("validation failed for mac address with zero value", !wifiAccessPoint.getMacAddress().equals("0")); + } } } -- cgit v1.2.3 From 627c077b4134b9ed31236b1c4dbd219091c22a77 Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Wed, 29 Jun 2022 09:09:26 +0200 Subject: test case for message with wifi but no cell towers --- src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java index 6f6298ffa..7eb167a74 100644 --- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -142,6 +142,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, buffer( "[ZJ*014111001350304*0038*008a*UD,070318,021027,V,00.000000,N,000.000000,E,0,0,0,0,100,18,1000,50,00000000,4,255,460,0,9346,5223,42,9346,5214,20,9784,4083,11,9346,5221,5]")); + + verifyPosition(decoder, buffer( + "[3G*8800000015*00DD*UD,010120,025946,V,0.0,N,0.0,E,22.0,0,-1,0,100,98,0,0,00000000,0,5,eduroam,f4:db:e6:d2:a8:00,-53,eduroam,f4:db:e6:da:d0:80,-79,eduroam,78:0c:f0:24:f9:80,-82,Lions,b0:be:76:0a:05:9a,-82,tubs-guest,f4:db:e6:d2:a8:01,-53,0.0]")); } -- cgit v1.2.3 From d9f127b979ff52731552edecd1d0762c21eb4403 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 07:16:25 -0700 Subject: Better MAC address validation --- src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java | 3 ++- src/test/java/org/traccar/ProtocolTest.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java index a45c315b3..635806b2d 100644 --- a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java @@ -116,8 +116,9 @@ public class B2316ProtocolDecoder extends BaseProtocolDecoder { String[] points = item.getString("wi").split(";"); for (String point : points) { String[] values = point.split(","); + String mac = values[0].replaceAll("(..)", "$1:"); network.addWifiAccessPoint(WifiAccessPoint.from( - values[0].replaceAll("(..)", "$1:"), Integer.parseInt(values[1]))); + mac.substring(0, mac.length() - 1), Integer.parseInt(values[1]))); } } diff --git a/src/test/java/org/traccar/ProtocolTest.java b/src/test/java/org/traccar/ProtocolTest.java index 3e27bbe28..5e37f44b9 100644 --- a/src/test/java/org/traccar/ProtocolTest.java +++ b/src/test/java/org/traccar/ProtocolTest.java @@ -323,7 +323,7 @@ public class ProtocolTest extends BaseTest { if (position.getNetwork().getWifiAccessPoints() != null) { for (WifiAccessPoint wifiAccessPoint : position.getNetwork().getWifiAccessPoints()) { - assertTrue("validation failed for mac address with zero value", !wifiAccessPoint.getMacAddress().equals("0")); + assertTrue(wifiAccessPoint.getMacAddress().matches("((\\p{XDigit}{2}):){5}(\\p{XDigit}{2})")); } } } -- cgit v1.2.3 From 7ca563cb9bf7a2fde68438b8ef1d09b7205edb8b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 09:16:15 -0700 Subject: Release GitHub action --- .github/workflows/release.yml | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..8183dd5f1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,43 @@ +name: Build installers + +on: + workflow_dispatch: + inputs: + version: + description: 'Version' + required: true + default: 'master' + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - uses: actions/setup-java@v3 + with: + distribution: zulu + java-version: 11 + - run: ./gradlew build + - uses: actions/setup-node@v3 + with: + node-version: 14 + - run: | + wget http://cdn.sencha.com/cmd/7.1.0.15/no-jre/SenchaCmd-7.1.0.15-linux-i386.sh.zip + unzip SenchaCmd-*.zip + ./SenchaCmd-*.sh -q + echo "$HOME/bin/Sencha/Cmd/" >> $GITHUB_PATH + - run: ./traccar-web/tools/package.sh + - run: | + sudo apt-get update + sudo apt-get install innoextract wine wine32 + - run: | + cd setup + wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe + wget https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-11.0.13.8-1/java-11-openjdk-11.0.13.8-1.windows.ojdkbuild.x86_64.zip + wget https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-x64.zip + wget https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-armhf.zip + ./package ${{ github.event.inputs.version }} -- cgit v1.2.3 From 66041463365f083ab97b76958d5afcfb7c38a6bd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 09:30:32 -0700 Subject: Update action --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8183dd5f1..134267bef 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,6 +17,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: true + - run: git --git-dir ./traccar-web/.git checkout ${{ github.ref_name }} - uses: actions/setup-java@v3 with: distribution: zulu @@ -33,7 +34,7 @@ jobs: - run: ./traccar-web/tools/package.sh - run: | sudo apt-get update - sudo apt-get install innoextract wine wine32 + sudo apt-get install innoextract wine - run: | cd setup wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe -- cgit v1.2.3 From e7216bd913bb8efc45751bb32d99577206d184d4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 09:53:27 -0700 Subject: Update scripts --- .github/workflows/release.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 134267bef..18fb8602b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,8 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - run: git --git-dir ./traccar-web/.git checkout ${{ github.ref_name }} + - run: git checkout ${{ github.ref_name }} + working-directory: ./traccar-web - uses: actions/setup-java@v3 with: distribution: zulu @@ -27,7 +28,7 @@ jobs: with: node-version: 14 - run: | - wget http://cdn.sencha.com/cmd/7.1.0.15/no-jre/SenchaCmd-7.1.0.15-linux-i386.sh.zip + wget -q http://cdn.sencha.com/cmd/7.1.0.15/no-jre/SenchaCmd-7.1.0.15-linux-i386.sh.zip unzip SenchaCmd-*.zip ./SenchaCmd-*.sh -q echo "$HOME/bin/Sencha/Cmd/" >> $GITHUB_PATH @@ -35,10 +36,11 @@ jobs: - run: | sudo apt-get update sudo apt-get install innoextract wine - - run: | - cd setup - wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe - wget https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-11.0.13.8-1/java-11-openjdk-11.0.13.8-1.windows.ojdkbuild.x86_64.zip - wget https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-x64.zip - wget https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-armhf.zip + - name: Build installers + working-directory: ./setup + run: | + wget -q http://files.jrsoftware.org/is/5/isetup-5.5.6.exe + wget -q https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-11.0.13.8-1/java-11-openjdk-11.0.13.8-1.windows.ojdkbuild.x86_64.zip + wget -q https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-x64.zip + wget -q https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-armhf.zip ./package ${{ github.event.inputs.version }} -- cgit v1.2.3 From 0ec7e53cde2515a87d2b2c74433688d9f30e7433 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 10:10:24 -0700 Subject: Update gradle task --- .github/workflows/gradle.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 42721d3fc..cbe2721bb 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -10,12 +10,12 @@ jobs: build: runs-on: ubuntu-latest - + steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 with: + distribution: zulu java-version: 11 - - name: Build with Gradle - run: ./gradlew build --warning-mode=fail + cache: gradle + - run: ./gradlew build --no-daemon --warning-mode=fail -- cgit v1.2.3 From 0297ce6150547b421fc98b42214b18f619485f0c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 10:16:26 -0700 Subject: More action fixes --- .github/workflows/release.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 18fb8602b..931ed2e94 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,10 +23,12 @@ jobs: with: distribution: zulu java-version: 11 + cache: gradle - run: ./gradlew build - uses: actions/setup-node@v3 with: node-version: 14 + cache: npm - run: | wget -q http://cdn.sencha.com/cmd/7.1.0.15/no-jre/SenchaCmd-7.1.0.15-linux-i386.sh.zip unzip SenchaCmd-*.zip @@ -43,4 +45,4 @@ jobs: wget -q https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-11.0.13.8-1/java-11-openjdk-11.0.13.8-1.windows.ojdkbuild.x86_64.zip wget -q https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-x64.zip wget -q https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-armhf.zip - ./package ${{ github.event.inputs.version }} + ./package.sh ${{ github.event.inputs.version }} -- cgit v1.2.3 From e06bb9d9e14d4606fb506cf72d59c753eddffd3f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 10:22:05 -0700 Subject: Update caching support --- .github/workflows/release.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 931ed2e94..66bd6c083 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,6 +29,9 @@ jobs: with: node-version: 14 cache: npm + cache-dependency-path: | + traccar-web/package-lock.json + traccar-web/modern/package-lock.json - run: | wget -q http://cdn.sencha.com/cmd/7.1.0.15/no-jre/SenchaCmd-7.1.0.15-linux-i386.sh.zip unzip SenchaCmd-*.zip -- cgit v1.2.3 From 9efc28ceaa3a232756bfd51140c8bfb85f207ee3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 10:48:46 -0700 Subject: Add missing package --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 66bd6c083..407bb9563 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: - run: ./traccar-web/tools/package.sh - run: | sudo apt-get update - sudo apt-get install innoextract wine + sudo apt-get install innoextract wine makeself - name: Build installers working-directory: ./setup run: | -- cgit v1.2.3 From 25b8d22a89eed6ba7ff7b70530461b80828f6b23 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 10:59:03 -0700 Subject: Another action fix --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 407bb9563..6f12f1477 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,8 +39,9 @@ jobs: echo "$HOME/bin/Sencha/Cmd/" >> $GITHUB_PATH - run: ./traccar-web/tools/package.sh - run: | + sudo dpkg --add-architecture i386 sudo apt-get update - sudo apt-get install innoextract wine makeself + sudo apt-get install innoextract makeself wine wine32 - name: Build installers working-directory: ./setup run: | -- cgit v1.2.3 From a64dfc52f2b20b718a9f724c6339e6cb647c1d71 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 11:00:14 -0700 Subject: Rename action --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6f12f1477..0cb51ddba 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: Build installers +name: Build Installers on: workflow_dispatch: -- cgit v1.2.3 From 7ab27c2601b626d87488ee0f1871a920857dae54 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 11:08:04 -0700 Subject: Attempt to fix wine --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0cb51ddba..7961fc6d9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,7 @@ jobs: - run: | sudo dpkg --add-architecture i386 sudo apt-get update - sudo apt-get install innoextract makeself wine wine32 + sudo apt-get install innoextract makeself wine32 - name: Build installers working-directory: ./setup run: | -- cgit v1.2.3 From edb8c63afb4d13158ec855b704f94a3e118d20f9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 11:24:37 -0700 Subject: Downgrade Ubuntu --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7961fc6d9..6a41bddcf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v3 -- cgit v1.2.3 From 8921fc12ea0590c290f3780fa20df7176b8c0000 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 11:55:16 -0700 Subject: Implement builds upload --- .github/workflows/release.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6a41bddcf..0b6f1baab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,7 +6,7 @@ on: version: description: 'Version' required: true - default: 'master' + default: 'preview' jobs: build: @@ -41,7 +41,7 @@ jobs: - run: | sudo dpkg --add-architecture i386 sudo apt-get update - sudo apt-get install innoextract makeself wine32 + sudo apt-get install innoextract makeself wine32 s3cmd - name: Build installers working-directory: ./setup run: | @@ -50,3 +50,9 @@ jobs: wget -q https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-x64.zip wget -q https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-armhf.zip ./package.sh ${{ github.event.inputs.version }} + - name: Upload installers + working-directory: ./setup + env: + S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }} + S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }} + run: s3cmd put traccar-*.zip s3://traccar/builds/ --host=nyc3.digitaloceanspaces.com --host-bucket=traccar --access_key="$S3_ACCESS_KEY" --secret_key="$S3_SECRET_KEY" -- cgit v1.2.3 From aed0411f4ae5cfc007d27e0521a39a242fab7840 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 17:03:23 -0700 Subject: Unify signed magnitude int decoding --- src/main/java/org/traccar/helper/BitUtil.java | 4 ++-- src/main/java/org/traccar/helper/BufferUtil.java | 6 ++++++ .../java/org/traccar/protocol/NiotProtocolDecoder.java | 11 +++-------- .../java/org/traccar/protocol/SigfoxProtocolDecoder.java | 15 +++------------ .../java/org/traccar/protocol/SuntechProtocolDecoder.java | 13 +++---------- .../org/traccar/protocol/ThinkPowerProtocolDecoder.java | 1 + src/test/java/org/traccar/helper/BufferUtilTest.java | 6 ++++++ 7 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/traccar/helper/BitUtil.java b/src/main/java/org/traccar/helper/BitUtil.java index b6108edff..829ddebc9 100644 --- a/src/main/java/org/traccar/helper/BitUtil.java +++ b/src/main/java/org/traccar/helper/BitUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,7 +21,7 @@ public final class BitUtil { } public static boolean check(long number, int index) { - return (number & (1 << index)) != 0; + return (number & (1L << index)) != 0; } public static int between(int number, int from, int to) { diff --git a/src/main/java/org/traccar/helper/BufferUtil.java b/src/main/java/org/traccar/helper/BufferUtil.java index 1e1a687fa..0dbe0a4ad 100644 --- a/src/main/java/org/traccar/helper/BufferUtil.java +++ b/src/main/java/org/traccar/helper/BufferUtil.java @@ -27,6 +27,12 @@ public final class BufferUtil { private BufferUtil() { } + public static int readSignedMagnitudeInt(ByteBuf buffer) { + long value = buffer.readUnsignedInt(); + int result = (int) BitUtil.to(value, 31); + return BitUtil.check(value, 31) ? -result : result; + } + public static int indexOf(ByteBuf buffer, int fromIndex, int toIndex, byte value, int count) { int startIndex = fromIndex; for (int i = 0; i < count; i++) { diff --git a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java index 16d992938..35614ccca 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BufferUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -57,12 +58,6 @@ public class NiotProtocolDecoder extends BaseProtocolDecoder { } } - private double readCoordinate(ByteBuf buf) { - long value = buf.readUnsignedInt(); - double result = BitUtil.to(value, 31) / 1800000.0; - return BitUtil.check(value, 31) ? -result : result; - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -96,8 +91,8 @@ public class NiotProtocolDecoder extends BaseProtocolDecoder { .setSecond(BcdUtil.readInteger(buf, 2)); position.setTime(dateBuilder.getDate()); - position.setLatitude(readCoordinate(buf)); - position.setLongitude(readCoordinate(buf)); + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) / 1800000.0); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) / 1800000.0); BcdUtil.readInteger(buf, 4); // reserved position.setCourse(BcdUtil.readInteger(buf, 4)); diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java index bbb8bc1cc..4ed2bb51d 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -22,6 +22,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.helper.BufferUtil; import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -159,18 +160,8 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { if (event == 0x0f || event == 0x1f) { position.setValid(event >> 4 > 0); - - long value; - value = buf.readUnsignedInt(); - position.setLatitude(BitUtil.to(value, 31) * 0.000001); - if (BitUtil.check(value, 31)) { - position.setLatitude(-position.getLatitude()); - } - value = buf.readUnsignedInt(); - position.setLongitude(BitUtil.to(value, 31) * 0.000001); - if (BitUtil.check(value, 31)) { - position.setLongitude(-position.getLongitude()); - } + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.000001); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.000001); position.set(Position.KEY_BATTERY, (int) buf.readUnsignedByte()); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 67a82a688..938d290c0 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -21,6 +21,7 @@ import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.config.Keys; +import org.traccar.helper.BufferUtil; import org.traccar.helper.model.AttributeUtil; import org.traccar.session.DeviceSession; import org.traccar.Protocol; @@ -673,19 +674,11 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(mask, 11)) { - long value = buf.readUnsignedInt(); - if (BitUtil.check(value, 31)) { - value = -BitUtil.to(value, 31); - } - position.setLatitude(value / 1000000.0); + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) / 1000000.0); } if (BitUtil.check(mask, 12)) { - long value = buf.readUnsignedInt(); - if (BitUtil.check(value, 31)) { - value = -BitUtil.to(value, 31); - } - position.setLongitude(value / 1000000.0); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) / 1000000.0); } if (BitUtil.check(mask, 13)) { diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java index 085ce4c91..26d60daba 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java @@ -19,6 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BitUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; diff --git a/src/test/java/org/traccar/helper/BufferUtilTest.java b/src/test/java/org/traccar/helper/BufferUtilTest.java index b539b5b28..0196cef9d 100644 --- a/src/test/java/org/traccar/helper/BufferUtilTest.java +++ b/src/test/java/org/traccar/helper/BufferUtilTest.java @@ -10,6 +10,12 @@ import static org.junit.Assert.assertEquals; public class BufferUtilTest { + @Test + public void testReadSignedMagnitudeInt() { + ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex("80000001")); + assertEquals(-1, BufferUtil.readSignedMagnitudeInt(buf)); + } + @Test public void test1() { ByteBuf buf = Unpooled.copiedBuffer("abcdef", StandardCharsets.US_ASCII); -- cgit v1.2.3 From ef523bb4db2c48d7d07a326157d5758199ed293f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 17:04:30 -0700 Subject: Fix ThinkPower negative coords --- src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java index 26d60daba..e7ab23e5b 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.helper.BitUtil; +import org.traccar.helper.BufferUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -65,8 +65,8 @@ public class ThinkPowerProtocolDecoder extends BaseProtocolDecoder { switch (type) { case 0x01: position.setValid(true); - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); + position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.0000001); + position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.0000001); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort() * 0.01); break; -- cgit v1.2.3 From e374041be79c95465cb4aea4d482ee90f5e531f5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 17:33:08 -0700 Subject: Decode TLW2-12BL network info --- src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 3 ++- src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index b7a89f2e9..6e09e6e3b 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -58,6 +58,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_DRIVER_BEHAVIOR_1 = 0x05; // 0x2626 public static final int MSG_DRIVER_BEHAVIOR_2 = 0x06; // 0x2626 public static final int MSG_BLE = 0x10; + public static final int MSG_NETWORK_2 = 0x11; public static final int MSG_GPS_2 = 0x13; public static final int MSG_ALARM_2 = 0x14; public static final int MSG_COMMAND = 0x81; @@ -167,7 +168,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return decodePosition(channel, deviceSession, buf, type, index, imei); - } else if (type == MSG_NETWORK && header == 0x2727) { + } else if (type == MSG_NETWORK && header == 0x2727 || type == MSG_NETWORK_2) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java index b5917e3cc..10d0aad59 100644 --- a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class T800xProtocolDecoderTest extends ProtocolTest { var decoder = inject(new T800xProtocolDecoder(null)); + verifyAttributes(decoder, binary( + "2525110055000208677300508924902206262035310c540045004c00430045004c0004454447450847534d20313930300f323134303734323036373835323839143839333430373131373930303936383037363846")); + verifyAttributes(decoder, binary( "27271000247bd00860112047066487210407034238000005d7d17365e625ff640a730148")); -- cgit v1.2.3 From 1089b4bd2c9721f88a898c69385ae3fcac4b6cbe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 19:02:15 -0700 Subject: Fix P61 battery decoding --- src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java | 7 ++++--- .../java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index ebd58ed5c..4cb4b420d 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 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -360,15 +360,16 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("d*,") .number("(x{1,2}),") // report type .number("d{1,2},") // count + .number("d*,").optional() // reserved .expression(PATTERN_LOCATION.pattern()) .groupBegin() - .number("(d{1,7}.d)?,").optional() // odometer + .number("(?:(d{1,7}.d)|0)?,").optional() // odometer .number("(d{1,3})?,") // battery .or() .number("(d{1,7}.d)?,") // odometer .groupEnd() .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) + .number("(dd)(dd)(dd)") // time (hhmmss) .text(",") .number("(xxxx)") // count number .text("$").optional() diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 6857feddc..1140aa110 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gl200TextProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "+RESP:GTNMR,423033,355197370058831,,0,0,0,1,0,0.0,298,182.7,-79.257983,43.875152,20220627132020,,,,,15,0,74,20220627144928,03CF$"), + Position.KEY_BATTERY_LEVEL, 74); + verifyPosition(decoder, buffer( "+RESP:GTFRI,5E0100,861971050039361,,,,10,1,1,10.4,140,196.9,-80.709946,35.016525,20220302220944,0310,0260,1CE9,52A1,00,0.0,,,,,420000,,,,20220302220948,1B0B$")); -- cgit v1.2.3 From 418e7ce116dd6c19b594f14ba220d3bdb905241c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 29 Jun 2022 19:23:19 -0700 Subject: Decode GV350MG driver warnings --- .../traccar/protocol/Gl200TextProtocolDecoder.java | 42 ++++++++++++++++++++++ .../protocol/Gl200TextProtocolDecoderTest.java | 4 +++ 2 files changed, 46 insertions(+) diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 4cb4b420d..517499f02 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -352,6 +352,22 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); + private static final Pattern PATTERN_DAR = new PatternBuilder() + .text("+RESP:GTDAR,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("(d),") // warning type + .number("(d{1,2}),,,") // fatigue degree + .expression(PATTERN_LOCATION.pattern()) + .any() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private static final Pattern PATTERN = new PatternBuilder() .text("+").expression("(?:RESP|BUFF):GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version @@ -1126,6 +1142,29 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private Object decodeDar(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_DAR, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + int warningType = parser.nextInt(); + int fatigueDegree = parser.nextInt(); + if (warningType == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); + position.set("fatigueDegree", fatigueDegree); + } else { + position.set("warningType", warningType); + } + + decodeLocation(position, parser); + + decodeDeviceTime(position, parser); + + return position; + } + private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) { Parser parser = new Parser(PATTERN, sentence); Position position = initPosition(parser, channel, remoteAddress); @@ -1317,6 +1356,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { case "PFA": result = decodePna(channel, remoteAddress, sentence); break; + case "DAR": + result = decodeDar(channel, remoteAddress, sentence); + break; default: result = decodeOther(channel, remoteAddress, sentence, type); break; diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 1140aa110..ef82a11a2 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gl200TextProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "+RESP:GTDAR,F10406,865284049582228,,4,0,,,1,18.5,0,129.4,114.015430,22.537279,20210922004634,0460,0000,27BD,0DFC,,,,20210922004635,082B$"), + "warningType", 4); + verifyAttribute(decoder, buffer( "+RESP:GTNMR,423033,355197370058831,,0,0,0,1,0,0.0,298,182.7,-79.257983,43.875152,20220627132020,,,,,15,0,74,20220627144928,03CF$"), Position.KEY_BATTERY_LEVEL, 74); -- cgit v1.2.3 From 8ea427480417580aab51ed8f291f53a4051c79ee Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 07:52:02 -0700 Subject: Extract device lookup --- .../org/traccar/database/DeviceLookupService.java | 57 ++++++++++++++++++++++ .../org/traccar/session/ConnectionManager.java | 19 +++----- 2 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/traccar/database/DeviceLookupService.java diff --git a/src/main/java/org/traccar/database/DeviceLookupService.java b/src/main/java/org/traccar/database/DeviceLookupService.java new file mode 100644 index 000000000..f0a4e7bf0 --- /dev/null +++ b/src/main/java/org/traccar/database/DeviceLookupService.java @@ -0,0 +1,57 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.database; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.model.Device; +import org.traccar.storage.Storage; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class DeviceLookupService { + + private static final Logger LOGGER = LoggerFactory.getLogger(DeviceLookupService.class); + + private final Storage storage; + + @Inject + public DeviceLookupService(Storage storage) { + this.storage = storage; + } + + public Device lookup(String[] uniqueIds) { + Device device = null; + try { + for (String uniqueId : uniqueIds) { + device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); + if (device != null) { + break; + } + } + } catch (Exception e) { + LOGGER.warn("Find device error", e); + } + return device; + } + +} diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 27d6184c2..abc13988d 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -26,6 +26,7 @@ import org.traccar.broadcast.BroadcastInterface; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.DeviceLookupService; import org.traccar.database.NotificationManager; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; @@ -76,6 +77,7 @@ public class ConnectionManager implements BroadcastInterface { private final NotificationManager notificationManager; private final Timer timer; private final BroadcastService broadcastService; + private final DeviceLookupService deviceLookupService; private final Map> listeners = new HashMap<>(); private final Map> userDevices = new HashMap<>(); @@ -86,7 +88,8 @@ public class ConnectionManager implements BroadcastInterface { @Inject public ConnectionManager( Injector injector, Config config, CacheManager cacheManager, Storage storage, - NotificationManager notificationManager, Timer timer, BroadcastService broadcastService) { + NotificationManager notificationManager, Timer timer, BroadcastService broadcastService, + DeviceLookupService deviceLookupService) { this.injector = injector; this.config = config; this.cacheManager = cacheManager; @@ -94,6 +97,7 @@ public class ConnectionManager implements BroadcastInterface { this.notificationManager = notificationManager; this.timer = timer; this.broadcastService = broadcastService; + this.deviceLookupService = deviceLookupService; deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT) * 1000; updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); broadcastService.registerListener(this); @@ -121,18 +125,7 @@ public class ConnectionManager implements BroadcastInterface { return endpointSessions.values().stream().findAny().orElse(null); } - Device device = null; - try { - for (String uniqueId : uniqueIds) { - device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); - if (device != null) { - break; - } - } - } catch (Exception e) { - LOGGER.warn("Find device error", e); - } + Device device = deviceLookupService.lookup(uniqueIds); if (device == null && config.getBoolean(Keys.DATABASE_REGISTER_UNKNOWN)) { device = addUnknownDevice(uniqueIds[0]); -- cgit v1.2.3 From 29ad12512ba5e109e78a3c8384ae10747e1eabec Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 09:12:01 -0700 Subject: Device lookup throttling --- .../org/traccar/database/DeviceLookupService.java | 83 ++++++++++++++++++++-- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/database/DeviceLookupService.java b/src/main/java/org/traccar/database/DeviceLookupService.java index f0a4e7bf0..9cf0899ee 100644 --- a/src/main/java/org/traccar/database/DeviceLookupService.java +++ b/src/main/java/org/traccar/database/DeviceLookupService.java @@ -15,40 +15,111 @@ */ package org.traccar.database; +import io.netty.util.Timeout; +import io.netty.util.Timer; +import io.netty.util.TimerTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.model.Device; import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; @Singleton public class DeviceLookupService { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceLookupService.class); + private static final long INFO_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(60); + private static final long THROTTLE_MIN_MS = TimeUnit.MINUTES.toMillis(1); + private static final long THROTTLE_MAX_MS = TimeUnit.MINUTES.toMillis(30); + private final Storage storage; + private final Timer timer; + + private static class IdentifierInfo { + private long lastQuery; + private long delay; + private Timeout timeout; + } + + private final class IdentifierTask implements TimerTask { + private final String uniqueId; + + private IdentifierTask(String uniqueId) { + this.uniqueId = uniqueId; + } + + @Override + public void run(Timeout timeout) { + LOGGER.debug("Device lookup expired {}", uniqueId); + synchronized (DeviceLookupService.this) { + identifierMap.remove(uniqueId); + } + } + } + + private final Map identifierMap = new ConcurrentHashMap<>(); @Inject - public DeviceLookupService(Storage storage) { + public DeviceLookupService(Storage storage, Timer timer) { this.storage = storage; + this.timer = timer; + } + + private synchronized boolean isThrottled(String uniqueId) { + IdentifierInfo info = identifierMap.get(uniqueId); + return info != null && System.currentTimeMillis() < info.lastQuery + info.delay; + } + + private synchronized void lookupSucceeded(String uniqueId) { + IdentifierInfo info = identifierMap.remove(uniqueId); + if (info != null) { + info.timeout.cancel(); + } + } + + private synchronized void lookupFailed(String uniqueId) { + IdentifierInfo info = identifierMap.get(uniqueId); + if (info != null) { + info.timeout.cancel(); + info.delay = Math.min(info.delay * 2, THROTTLE_MAX_MS); + } else { + info = new IdentifierInfo(); + identifierMap.put(uniqueId, info); + info.delay = THROTTLE_MIN_MS; + } + info.lastQuery = System.currentTimeMillis(); + info.timeout = timer.newTimeout(new IdentifierTask(uniqueId), INFO_TIMEOUT_MS, TimeUnit.MILLISECONDS); + LOGGER.debug("Device lookup {} throttled for {} ms", uniqueId, info.delay); } public Device lookup(String[] uniqueIds) { Device device = null; try { for (String uniqueId : uniqueIds) { - device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); - if (device != null) { - break; + if (!isThrottled(uniqueId)) { + device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); + if (device != null) { + lookupSucceeded(uniqueId); + break; + } else { + lookupFailed(uniqueId); + } + } else { + LOGGER.debug("Device lookup throttled {}", uniqueId); } } - } catch (Exception e) { + } catch (StorageException e) { LOGGER.warn("Find device error", e); } return device; -- cgit v1.2.3 From 45c076da2d5be1cad89a9a7e1c0dc2d3755bd7b5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 09:15:19 -0700 Subject: Fix online device removal --- .../org/traccar/session/cache/CacheManager.java | 56 +++++++++++----------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index bc5fc357f..9d1db7d14 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -268,38 +268,40 @@ public class CacheManager implements BroadcastInterface { Device device = storage.getObject(Device.class, new Request( new Columns.All(), new Condition.Equals("id", "id", deviceId))); - addObject(deviceId, device); + if (device != null) { + addObject(deviceId, device); + + for (Class clazz : CLASSES) { + var objects = storage.getObjects(clazz, new Request( + new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); + links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toList())); + objects.forEach(object -> addObject(deviceId, object)); + } - for (Class clazz : CLASSES) { - var objects = storage.getObjects(clazz, new Request( - new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); - links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toList())); - objects.forEach(object -> addObject(deviceId, object)); - } + var users = storage.getObjects(User.class, new Request( + new Columns.All(), new Condition.Permission(User.class, Device.class, deviceId))); + links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toList())); + for (var user : users) { + addObject(deviceId, user); + var notifications = storage.getObjects(Notification.class, new Request( + new Columns.All(), new Condition.Permission(User.class, user.getId(), Notification.class))); + notifications.stream() + .filter(Notification::getAlways) + .forEach(object -> { + links.computeIfAbsent(Notification.class, k -> new LinkedList<>()).add(object.getId()); + addObject(deviceId, object); + }); + } - var users = storage.getObjects(User.class, new Request( - new Columns.All(), new Condition.Permission(User.class, Device.class, deviceId))); - links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toList())); - for (var user : users) { - addObject(deviceId, user); - var notifications = storage.getObjects(Notification.class, new Request( - new Columns.All(), new Condition.Permission(User.class, user.getId(), Notification.class))); - notifications.stream() - .filter(Notification::getAlways) - .forEach(object -> { - links.computeIfAbsent(Notification.class, k -> new LinkedList<>()).add(object.getId()); - addObject(deviceId, object); - }); - } + deviceLinks.put(deviceId, links); - deviceLinks.put(deviceId, links); + if (device.getPositionId() > 0) { + devicePositions.put(deviceId, storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); + } - if (device.getPositionId() > 0) { - devicePositions.put(deviceId, storage.getObject(Position.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); + invalidateDeviceGeofences(device); } - - invalidateDeviceGeofences(device); } private void unsafeRemoveDevice(long deviceId) { -- cgit v1.2.3 From 12e36b50fe063bd7ec93464b035d78376f7e9046 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 09:18:53 -0700 Subject: Remove script in favor of action --- setup/environment.sh | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 setup/environment.sh diff --git a/setup/environment.sh b/setup/environment.sh deleted file mode 100644 index 86a50cc85..000000000 --- a/setup/environment.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -add-apt-repository ppa:openjdk-r/ppa -curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - -dpkg --add-architecture i386 -apt update -apt install -y git openjdk-11-jdk zip unzip innoextract wine wine32 makeself nodejs - -# /usr/bin/printf '\xfe\xed\xfe\xed\x00\x00\x00\x02\x00\x00\x00\x00\xe2\x68\x6e\x45\xfb\x43\xdf\xa4\xd9\x92\xdd\x41\xce\xb6\xb2\x1c\x63\x30\xd7\x92' > /etc/ssl/certs/java/cacerts -# /var/lib/dpkg/info/ca-certificates-java.postinst configure - -git clone --recurse-submodules https://github.com/traccar/traccar.git -(cd traccar/traccar-web && git checkout master) -(cd traccar && ./gradlew build) - -wget http://cdn.sencha.com/cmd/7.1.0.15/no-jre/SenchaCmd-7.1.0.15-linux-i386.sh.zip -unzip SenchaCmd-*.zip ; rm SenchaCmd-*.zip -./SenchaCmd-*.sh -q ; rm SenchaCmd-* -export PATH=$PATH:~/bin/Sencha/Cmd/ - -(cd traccar/traccar-web && ./tools/package.sh) - -cd traccar/setup -wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe -wget https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-11.0.13.8-1/java-11-openjdk-11.0.13.8-1.windows.ojdkbuild.x86_64.zip -wget https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-x64.zip -wget https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-armhf.zip -- cgit v1.2.3 From 7b23cebec889705f271bc472a7e62851d7177303 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 13:12:59 -0700 Subject: Upload public files --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0b6f1baab..beeafe58f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,4 +55,4 @@ jobs: env: S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }} S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }} - run: s3cmd put traccar-*.zip s3://traccar/builds/ --host=nyc3.digitaloceanspaces.com --host-bucket=traccar --access_key="$S3_ACCESS_KEY" --secret_key="$S3_SECRET_KEY" + run: s3cmd --acl-public put traccar-*.zip s3://traccar/builds/ --host=nyc3.digitaloceanspaces.com --host-bucket=traccar --access_key="$S3_ACCESS_KEY" --secret_key="$S3_SECRET_KEY" -- cgit v1.2.3 From d7c1345f6f070e3931af0ad3fac785130cc9f4dc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 17:16:03 -0700 Subject: Fix group attribute lookup (fix #4880) --- src/main/java/org/traccar/helper/model/AttributeUtil.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java index b438f97dc..43558e8f7 100644 --- a/src/main/java/org/traccar/helper/model/AttributeUtil.java +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -19,6 +19,7 @@ import org.traccar.config.ConfigKey; import org.traccar.config.KeyType; import org.traccar.config.Keys; import org.traccar.model.Device; +import org.traccar.model.Group; import org.traccar.session.cache.CacheManager; public final class AttributeUtil { @@ -30,6 +31,16 @@ public final class AttributeUtil { public static T lookup(CacheManager cacheManager, ConfigKey key, long deviceId) { Device device = cacheManager.getObject(Device.class, deviceId); Object result = device.getAttributes().get(key.getKey()); + long groupId = device.getGroupId(); + while (result == null && groupId > 0) { + Group group = cacheManager.getObject(Group.class, groupId); + if (group != null) { + result = group.getAttributes().get(key.getKey()); + groupId = group.getGroupId(); + } else { + groupId = 0; + } + } if (result == null && key.hasType(KeyType.SERVER)) { result = cacheManager.getServer().getAttributes().get(key.getKey()); } -- cgit v1.2.3 From 771f334d686b252b3b6975beb758c3833e85f0f2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 30 Jun 2022 17:55:43 -0700 Subject: Check for attribute --- src/main/java/org/traccar/handler/CopyAttributesHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index 405a52ecd..50d36471a 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -44,7 +44,7 @@ public class CopyAttributesHandler extends BaseDataHandler { String attributesString = AttributeUtil.lookup( cacheManager, Keys.PROCESSING_COPY_ATTRIBUTES, position.getDeviceId()); Position last = cacheManager.getPosition(position.getDeviceId()); - if (last != null) { + if (last != null && attributesString != null) { for (String attribute : attributesString.split("[ ,]")) { if (last.getAttributes().containsKey(attribute) && !position.getAttributes().containsKey(attribute)) { -- cgit v1.2.3 From 8c4499a8fa5e30a498d9357b16b56cd65fbe1e39 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 1 Jul 2022 10:01:45 -0700 Subject: Fix duplicated users --- src/main/java/org/traccar/session/cache/CacheManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 9d1db7d14..cd71f5f9f 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -249,6 +249,7 @@ public class CacheManager implements BroadcastInterface { } private void invalidateUsers() throws StorageException { + notificationUsers.clear(); Map users = new HashMap<>(); storage.getObjects(User.class, new Request(new Columns.All())) .forEach(user -> users.put(user.getId(), user)); -- cgit v1.2.3 From 95ba3446d936213683d604eb545710124b9bf689 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 2 Jul 2022 09:06:49 -0700 Subject: Add broadcast logging --- src/main/java/org/traccar/broadcast/MulticastBroadcastService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index ac0fcbd86..81b6cd5ec 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -159,6 +159,7 @@ public class MulticastBroadcastService implements BroadcastService { DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); socket.receive(packet); String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); + LOGGER.info("Broadcast received: {}", data); handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); } socket.leaveGroup(address); -- cgit v1.2.3 From 5f88528350f55802d63bfcb0f4902a4a3399634c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 3 Jul 2022 13:03:24 -0700 Subject: Fix server update --- src/main/java/org/traccar/api/resource/ServerResource.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 2ef99c578..071b7ae8e 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -22,9 +22,10 @@ import org.traccar.helper.Log; import org.traccar.helper.LogAction; import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.storage.Storage; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.annotation.Nullable; @@ -48,7 +49,7 @@ import java.util.TimeZone; public class ServerResource extends BaseResource { @Inject - private Storage storage; + private CacheManager cacheManager; @Inject private MailManager mailManager; @@ -72,6 +73,10 @@ public class ServerResource extends BaseResource { @PUT public Response update(Server entity) throws StorageException { permissionsService.checkAdmin(getUserId()); + storage.updateObject(entity, new Request( + new Columns.Exclude("id"), + new Condition.Equals("id", "id"))); + cacheManager.updateOrInvalidate(entity); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); } -- cgit v1.2.3 From c49bda5396847731f4eea8f6e3f0e0dd6811ae6f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 3 Jul 2022 15:52:39 -0700 Subject: Support KML export (fix #1858, fix #2329) --- .../org/traccar/api/resource/PositionResource.java | 21 ++++++ .../org/traccar/reports/KmlExportProvider.java | 80 ++++++++++++++++++++++ tools/test-generator.py | 7 +- 3 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/traccar/reports/KmlExportProvider.java diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index cac64feb1..28f8eb600 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -20,17 +20,22 @@ import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.UserRestrictions; +import org.traccar.reports.KmlExportProvider; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; +import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -41,6 +46,9 @@ import java.util.List; @Consumes(MediaType.APPLICATION_JSON) public class PositionResource extends BaseResource { + @Inject + private KmlExportProvider kmlExportProvider; + @GET public Collection getJson( @QueryParam("deviceId") long deviceId, @QueryParam("id") List positionIds, @@ -69,4 +77,17 @@ public class PositionResource extends BaseResource { } } + @Path("kml") + @GET + @Produces("application/vnd.google-earth.kml+xml") + public Response getKml( + @QueryParam("deviceId") long deviceId, + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + kmlExportProvider.generateKml(stream, deviceId, from, to); + return Response.ok(stream.toByteArray()) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.kml").build(); + } + } diff --git a/src/main/java/org/traccar/reports/KmlExportProvider.java b/src/main/java/org/traccar/reports/KmlExportProvider.java new file mode 100644 index 000000000..977897833 --- /dev/null +++ b/src/main/java/org/traccar/reports/KmlExportProvider.java @@ -0,0 +1,80 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.reports; + +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Device; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.stream.Collectors; + +public class KmlExportProvider { + + private final Storage storage; + + @Inject + public KmlExportProvider(Storage storage) { + this.storage = storage; + } + + public void generateKml( + OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { + + var device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId))); + var positions = PositionUtil.getPositions(storage, deviceId, from, to); + + var dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + + try (PrintWriter writer = new PrintWriter(outputStream)) { + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(device.getName()); + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(dateFormat.format(from)); + writer.print(" - "); + writer.print(dateFormat.format(to)); + writer.print(""); + writer.print(""); + writer.print("1"); + writer.print("1"); + writer.print("absolute"); + writer.print(""); + writer.print(positions.stream() + .map((p -> String.format("%f,%f,%f", p.getLongitude(), p.getLatitude(), p.getAltitude()))) + .collect(Collectors.joining(" "))); + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(""); + } + } + +} diff --git a/tools/test-generator.py b/tools/test-generator.py index b8a06ac32..eb50d2600 100755 --- a/tools/test-generator.py +++ b/tools/test-generator.py @@ -35,8 +35,8 @@ for i in range(0, len(waypoints)): lon = lon1 + (lon2 - lon1) * j / count points.append((lat, lon)) -def send(conn, lat, lon, course, speed, battery, alarm, ignition, accuracy, rpm, fuel, driverUniqueId): - params = (('id', id), ('timestamp', int(time.time())), ('lat', lat), ('lon', lon), ('bearing', course), ('speed', speed), ('batt', battery)) +def send(conn, lat, lon, altitude, course, speed, battery, alarm, ignition, accuracy, rpm, fuel, driverUniqueId): + params = (('id', id), ('timestamp', int(time.time())), ('lat', lat), ('lon', lon), ('altitude', altitude), ('bearing', course), ('speed', speed), ('batt', battery)) if alarm: params = params + (('alarm', 'sos'),) if ignition: @@ -70,6 +70,7 @@ conn = httplib.HTTPConnection(server) while True: (lat1, lon1) = points[index % len(points)] (lat2, lon2) = points[(index + 1) % len(points)] + altitude = 50 speed = device_speed if (index % len(points)) != 0 else 0 alarm = (index % 10) == 0 battery = random.randint(0, 100) @@ -78,6 +79,6 @@ while True: rpm = random.randint(500, 4000) fuel = random.randint(0, 80) driverUniqueId = driver_id if (index % len(points)) == 0 else False - send(conn, lat1, lon1, course(lat1, lon1, lat2, lon2), speed, battery, alarm, ignition, accuracy, rpm, fuel, driverUniqueId) + send(conn, lat1, lon1, altitude, course(lat1, lon1, lat2, lon2), speed, battery, alarm, ignition, accuracy, rpm, fuel, driverUniqueId) time.sleep(period) index += 1 -- cgit v1.2.3 From d25e8a163786c78098c57bb78cf44746c1fe2364 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 3 Jul 2022 16:02:49 -0700 Subject: Geocoder enabled server flag --- src/main/java/org/traccar/api/resource/ServerResource.java | 1 + src/main/java/org/traccar/model/Server.java | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 071b7ae8e..3e6792f5b 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -63,6 +63,7 @@ public class ServerResource extends BaseResource { public Server get() throws StorageException { Server server = storage.getObject(Server.class, new Request(new Columns.All())); server.setEmailEnabled(mailManager.getEmailEnabled()); + server.setGeocoderEnabled(geocoder != null); User user = permissionsService.getUser(getUserId()); if (user != null && user.getAdministrator()) { server.setStorageSpace(Log.getStorageSpace()); diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index 648be2991..e39da1b16 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -214,6 +214,18 @@ public class Server extends ExtendedModel implements UserRestrictions { return emailEnabled; } + private boolean geocoderEnabled; + + @QueryIgnore + public void setGeocoderEnabled(boolean geocoderEnabled) { + this.geocoderEnabled = geocoderEnabled; + } + + @QueryIgnore + public boolean getGeocoderEnabled() { + return geocoderEnabled; + } + private long[] storageSpace; @QueryIgnore -- cgit v1.2.3 From aa032baf7349d103cbb3592cfe08a5a0b45a1ff3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 3 Jul 2022 20:19:22 -0700 Subject: Debug media folder path --- debug.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debug.xml b/debug.xml index 50e70c812..debbd06b7 100644 --- a/debug.xml +++ b/debug.xml @@ -11,6 +11,8 @@ true true + ./target/media + true true -- cgit v1.2.3 From 0112af2cf93743b2bcec0e16cd0d95bcc9713f3f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Jul 2022 09:26:43 -0700 Subject: Add device image upload --- .../org/traccar/api/resource/DeviceResource.java | 36 +++++++++++++++++++++- .../java/org/traccar/database/MediaManager.java | 5 +++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 8791a82f9..1d9bc20ec 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseObjectResource; import org.traccar.broadcast.BroadcastService; +import org.traccar.database.MediaManager; import org.traccar.helper.LogAction; import org.traccar.model.Device; import org.traccar.model.DeviceAccumulators; @@ -32,12 +33,18 @@ import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.util.Collection; import java.util.LinkedList; @@ -57,6 +64,9 @@ public class DeviceResource extends BaseObjectResource { @Inject private BroadcastService broadcastService; + @Inject + private MediaManager mediaManager; + public DeviceResource() { super(Device.class); } @@ -110,7 +120,7 @@ public class DeviceResource extends BaseObjectResource { @Path("{id}/accumulators") @PUT - public Response updateAccumulators(DeviceAccumulators entity) throws StorageException, IOException { + public Response updateAccumulators(DeviceAccumulators entity) throws StorageException { if (permissionsService.notAdmin(getUserId())) { permissionsService.checkManager(getUserId()); permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); @@ -149,4 +159,28 @@ public class DeviceResource extends BaseObjectResource { return Response.noContent().build(); } + @Path("{id}/image") + @POST + @Consumes("image/*") + public Response uploadImage( + @PathParam("id") long deviceId, File file, + @HeaderParam(HttpHeaders.CONTENT_TYPE) String type) throws StorageException, IOException { + + Device device = storage.getObject(Device.class, new Request( + new Columns.All(), + new Condition.And( + new Condition.Equals("id", "id", deviceId), + new Condition.Permission(User.class, getUserId(), Device.class)))); + if (device != null) { + String name = "device"; + String extension = type.substring("image/".length()); + try (var input = new FileInputStream(file); + var output = mediaManager.createFileStream(device.getUniqueId(), name, extension)) { + input.transferTo(output); + } + return Response.ok(name + "." + extension).build(); + } + return Response.status(Response.Status.NOT_FOUND).build(); + } + } diff --git a/src/main/java/org/traccar/database/MediaManager.java b/src/main/java/org/traccar/database/MediaManager.java index 5f3fdcdf7..2b3e3e1ee 100644 --- a/src/main/java/org/traccar/database/MediaManager.java +++ b/src/main/java/org/traccar/database/MediaManager.java @@ -25,6 +25,7 @@ import javax.inject.Inject; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Files; @@ -53,6 +54,10 @@ public class MediaManager { return filePath.toFile(); } + public OutputStream createFileStream(String uniqueId, String name, String extension) throws IOException { + return new FileOutputStream(createFile(uniqueId, name + "." + extension)); + } + public String writeFile(String uniqueId, ByteBuf buf, String extension) { if (path != null) { int size = buf.readableBytes(); -- cgit v1.2.3 From 8a5dbe0a1bd68c21d4c1e06a55e1190246774a1f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Jul 2022 14:30:11 -0700 Subject: Implement CSV export (fix #2961) --- .../org/traccar/api/resource/PositionResource.java | 36 ++++++++-- src/main/java/org/traccar/model/Position.java | 1 - .../org/traccar/reports/CsvExportProvider.java | 76 ++++++++++++++++++++++ .../org/traccar/reports/KmlExportProvider.java | 2 +- 4 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/traccar/reports/CsvExportProvider.java diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 28f8eb600..b4c8d18b9 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -20,6 +20,7 @@ import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.UserRestrictions; +import org.traccar.reports.CsvExportProvider; import org.traccar.reports.KmlExportProvider; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -32,10 +33,11 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.io.ByteArrayOutputStream; +import javax.ws.rs.core.StreamingOutput; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -49,6 +51,9 @@ public class PositionResource extends BaseResource { @Inject private KmlExportProvider kmlExportProvider; + @Inject + private CsvExportProvider csvExportProvider; + @GET public Collection getJson( @QueryParam("deviceId") long deviceId, @QueryParam("id") List positionIds, @@ -84,10 +89,33 @@ public class PositionResource extends BaseResource { @QueryParam("deviceId") long deviceId, @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { permissionsService.checkPermission(Device.class, getUserId(), deviceId); - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - kmlExportProvider.generateKml(stream, deviceId, from, to); - return Response.ok(stream.toByteArray()) + StreamingOutput stream = output -> { + try { + kmlExportProvider.generate(output, deviceId, from, to); + } catch (StorageException e) { + throw new WebApplicationException(e); + } + }; + return Response.ok(stream) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.kml").build(); } + @Path("csv") + @GET + @Produces("text/csv") + public Response getCsv( + @QueryParam("deviceId") long deviceId, + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + StreamingOutput stream = output -> { + try { + csvExportProvider.generate(output, deviceId, from, to); + } catch (StorageException e) { + throw new WebApplicationException(e); + } + }; + return Response.ok(stream) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.csv").build(); + } + } diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 348370e2c..d6c985458 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -150,7 +150,6 @@ public class Position extends Message { public Position(String protocol) { this.protocol = protocol; - this.serverTime = new Date(); } private String protocol; diff --git a/src/main/java/org/traccar/reports/CsvExportProvider.java b/src/main/java/org/traccar/reports/CsvExportProvider.java new file mode 100644 index 000000000..df55c470e --- /dev/null +++ b/src/main/java/org/traccar/reports/CsvExportProvider.java @@ -0,0 +1,76 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.reports; + +import org.traccar.helper.DateUtil; +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Position; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; + +import javax.inject.Inject; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class CsvExportProvider { + + private final Storage storage; + + @Inject + public CsvExportProvider(Storage storage) { + this.storage = storage; + } + + public void generate( + OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { + + var positions = PositionUtil.getPositions(storage, deviceId, from, to); + + var attributes = positions.stream() + .flatMap((position -> position.getAttributes().keySet().stream())) + .collect(Collectors.toUnmodifiableSet()); + + var properties = new LinkedHashMap>(); + properties.put("id", Position::getId); + properties.put("deviceId", Position::getDeviceId); + properties.put("protocol", Position::getProtocol); + properties.put("serverTime", position -> DateUtil.formatDate(position.getServerTime())); + properties.put("deviceTime", position -> DateUtil.formatDate(position.getDeviceTime())); + properties.put("fixTime", position -> DateUtil.formatDate(position.getFixTime())); + properties.put("valid", Position::getValid); + properties.put("latitude", Position::getLatitude); + properties.put("longitude", Position::getLongitude); + properties.put("altitude", Position::getAltitude); + properties.put("speed", Position::getSpeed); + properties.put("course", Position::getCourse); + properties.put("address", Position::getAddress); + properties.put("accuracy", Position::getAccuracy); + attributes.forEach(key -> properties.put(key, position -> position.getAttributes().get(key))); + + try (PrintWriter writer = new PrintWriter(outputStream)) { + writer.println(String.join(",", properties.keySet())); + positions.forEach(position -> writer.println(properties.values().stream() + .map(f -> Objects.toString(f.apply(position), "")) + .collect(Collectors.joining(",")))); + } + } + +} diff --git a/src/main/java/org/traccar/reports/KmlExportProvider.java b/src/main/java/org/traccar/reports/KmlExportProvider.java index 977897833..e8b5c4278 100644 --- a/src/main/java/org/traccar/reports/KmlExportProvider.java +++ b/src/main/java/org/traccar/reports/KmlExportProvider.java @@ -39,7 +39,7 @@ public class KmlExportProvider { this.storage = storage; } - public void generateKml( + public void generate( OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { var device = storage.getObject(Device.class, new Request( -- cgit v1.2.3 From 0b463a40998baf05cc84cb4400ab58e6e11c909d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Jul 2022 15:25:03 -0700 Subject: Additional report endpoints --- .../org/traccar/api/resource/ReportResource.java | 221 ++++++++++++++------- 1 file changed, 154 insertions(+), 67 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 3955f1d20..6176013c1 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -16,26 +16,6 @@ */ package org.traccar.api.resource; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Collection; -import java.util.Date; -import java.util.List; - -import javax.activation.DataHandler; -import javax.inject.Inject; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; -import javax.mail.util.ByteArrayDataSource; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.api.BaseResource; @@ -46,15 +26,38 @@ import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.reports.EventsReportProvider; +import org.traccar.reports.RouteReportProvider; +import org.traccar.reports.StopsReportProvider; import org.traccar.reports.SummaryReportProvider; import org.traccar.reports.TripsReportProvider; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.SummaryReportItem; import org.traccar.reports.model.TripReportItem; -import org.traccar.reports.RouteReportProvider; -import org.traccar.reports.StopsReportProvider; import org.traccar.storage.StorageException; +import javax.activation.DataHandler; +import javax.inject.Inject; +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; +import javax.mail.util.ByteArrayDataSource; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collection; +import java.util.Date; +import java.util.List; + @Path("reports") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -62,8 +65,7 @@ public class ReportResource extends BaseResource { private static final Logger LOGGER = LoggerFactory.getLogger(ReportResource.class); - private static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; - private static final String CONTENT_DISPOSITION_VALUE_XLSX = "attachment; filename=report.xlsx"; + private static final String EXCEL = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; @Inject private EventsReportProvider eventsReportProvider; @@ -84,19 +86,18 @@ public class ReportResource extends BaseResource { private MailManager mailManager; private interface ReportExecutor { - void execute(ByteArrayOutputStream stream) throws StorageException, IOException; + void execute(OutputStream stream) throws StorageException, IOException; } private Response executeReport( - long userId, boolean mail, ReportExecutor executor) throws StorageException, IOException { - final ByteArrayOutputStream stream = new ByteArrayOutputStream(); + long userId, boolean mail, ReportExecutor executor) { if (mail) { new Thread(() -> { try { + var stream = new ByteArrayOutputStream(); executor.execute(stream); MimeBodyPart attachment = new MimeBodyPart(); - attachment.setFileName("report.xlsx"); attachment.setDataHandler(new DataHandler(new ByteArrayDataSource( stream.toByteArray(), "application/octet-stream"))); @@ -109,17 +110,25 @@ public class ReportResource extends BaseResource { }).start(); return Response.noContent().build(); } else { - executor.execute(stream); - return Response.ok(stream.toByteArray()) - .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build(); + StreamingOutput stream = output -> { + try { + executor.execute(output); + } catch (StorageException e) { + throw new WebApplicationException(e); + } + }; + return Response.ok(stream) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=report.xlsx").build(); } } @Path("route") @GET public Collection getRoute( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); return routeReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); @@ -127,11 +136,13 @@ public class ReportResource extends BaseResource { @Path("route") @GET - @Produces(XLSX) + @Produces(EXCEL) public Response getRouteExcel( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws StorageException, IOException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("mail") boolean mail) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "route", from, to, deviceIds, groupIds); @@ -139,12 +150,26 @@ public class ReportResource extends BaseResource { }); } + @Path("route/{type:xlsx|mail}") + @GET + @Produces(EXCEL) + public Response getRouteExcel( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") final List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @PathParam("type") String type) throws StorageException { + return getRouteExcel(deviceIds, groupIds, from, to, type.equals("mail")); + } + @Path("events") @GET public Collection getEvents( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("type") final List types, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("type") List types, + @QueryParam("from") Date from, + @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); return eventsReportProvider.getObjects(getUserId(), deviceIds, groupIds, types, from, to); @@ -152,12 +177,14 @@ public class ReportResource extends BaseResource { @Path("events") @GET - @Produces(XLSX) + @Produces(EXCEL) public Response getEventsExcel( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("type") final List types, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws StorageException, IOException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("type") List types, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("mail") boolean mail) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "events", from, to, deviceIds, groupIds); @@ -165,12 +192,27 @@ public class ReportResource extends BaseResource { }); } + @Path("events/{type:xlsx|mail}") + @GET + @Produces(EXCEL) + public Response getEventsExcel( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("type") List types, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @PathParam("type") String type) throws StorageException { + return getEventsExcel(deviceIds, groupIds, types, from, to, type.equals("mail")); + } + @Path("summary") @GET public Collection getSummary( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily) - throws StorageException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("daily") boolean daily) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); return summaryReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to, daily); @@ -178,12 +220,14 @@ public class ReportResource extends BaseResource { @Path("summary") @GET - @Produces(XLSX) + @Produces(EXCEL) public Response getSummaryExcel( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("daily") boolean daily, - @QueryParam("mail") boolean mail) - throws StorageException, IOException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("daily") boolean daily, + @QueryParam("mail") boolean mail) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "summary", from, to, deviceIds, groupIds); @@ -191,12 +235,26 @@ public class ReportResource extends BaseResource { }); } + @Path("summary/{type:xlsx|mail}") + @GET + @Produces(EXCEL) + public Response getSummaryExcel( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("daily") boolean daily, + @PathParam("type") String type) throws StorageException { + return getSummaryExcel(deviceIds, groupIds, from, to, daily, type.equals("mail")); + } + @Path("trips") @GET - @Produces(MediaType.APPLICATION_JSON) public Collection getTrips( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); return tripsReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); @@ -204,11 +262,13 @@ public class ReportResource extends BaseResource { @Path("trips") @GET - @Produces(XLSX) + @Produces(EXCEL) public Response getTripsExcel( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws StorageException, IOException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("mail") boolean mail) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "trips", from, to, deviceIds, groupIds); @@ -216,12 +276,25 @@ public class ReportResource extends BaseResource { }); } + @Path("trips/{type:xlsx|mail}") + @GET + @Produces(EXCEL) + public Response getTripsExcel( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @PathParam("type") String type) throws StorageException { + return getTripsExcel(deviceIds, groupIds, from, to, type.equals("mail")); + } + @Path("stops") @GET - @Produces(MediaType.APPLICATION_JSON) public Collection getStops( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); return stopsReportProvider.getObjects(getUserId(), deviceIds, groupIds, from, to); @@ -229,11 +302,13 @@ public class ReportResource extends BaseResource { @Path("stops") @GET - @Produces(XLSX) + @Produces(EXCEL) public Response getStopsExcel( - @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, - @QueryParam("from") Date from, @QueryParam("to") Date to, @QueryParam("mail") boolean mail) - throws StorageException, IOException { + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @QueryParam("mail") boolean mail) throws StorageException { permissionsService.checkRestriction(getUserId(), UserRestrictions::getDisableReports); return executeReport(getUserId(), mail, stream -> { LogAction.logReport(getUserId(), "stops", from, to, deviceIds, groupIds); @@ -241,4 +316,16 @@ public class ReportResource extends BaseResource { }); } + @Path("stops/{type:xlsx|mail}") + @GET + @Produces(EXCEL) + public Response getStopsExcel( + @QueryParam("deviceId") List deviceIds, + @QueryParam("groupId") List groupIds, + @QueryParam("from") Date from, + @QueryParam("to") Date to, + @PathParam("type") String type) throws StorageException { + return getStopsExcel(deviceIds, groupIds, from, to, type.equals("mail")); + } + } -- cgit v1.2.3 From 715499d5eabf73bdd1684bcf87006d904c92414b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 5 Jul 2022 17:12:08 -0700 Subject: Trim Suntech serial data --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 938d290c0..52fdaa05c 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -400,7 +400,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } } } else { - position.set("serial", attribute); + position.set("serial", attribute.trim()); } remaining -= attribute.length() + 1; } diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 71f71ce99..30959c8b9 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -95,6 +95,10 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, binary( "53543330305545583b3531313639393339383b34353b3331353b32303232303632333b31383a32343a35383b3661313332393b2d32392e3735343934373b2d3035372e3038353838353b3030302e3030303b3030302e30303b31303b313b37323b302e30303b3030303030303b31323b0201100110011090011001100110011001100110fe3b39303b3030303030303b332e393b313b30303030303030303030303030303b30")); + verifyAttribute(decoder, buffer( + "ST300UEX;511248287;45;311;20220701;18:42:08;14c943;-22.975257;-043.373065;000.000;000.00;0;0;0;12.14;100010;19;RFID:008FB2BEBA39\r\n;3E;000135;4.1;1;00000000000000;0"), + "serial", "RFID:008FB2BEBA39"); + verifyAttribute(decoder, buffer( "ST300UEX;100850000;01;010;20081017;07:41:56;2F100;+37.478519;+126.886819;000.012;000.00;9;1;0;15.30;001100;25;Welcome to Suntech World!;12;0;4.5;1"), "serial", "Welcome to Suntech World!"); -- cgit v1.2.3 From 09eebb35449c4ffb43b6a72bb4c3f723ec1c84be Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 6 Jul 2022 16:19:56 -0700 Subject: Remove motion fallback (fix #3257) --- src/main/java/org/traccar/reports/common/ReportUtils.java | 7 +------ src/test/java/org/traccar/reports/ReportUtilsTest.java | 1 + 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index cd6b6ffd5..ce5e3d8d4 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -341,12 +341,7 @@ public class ReportUtils { return false; } } - if (positions.get(index).getAttributes().containsKey(Position.KEY_MOTION) - && positions.get(index).getAttributes().get(Position.KEY_MOTION) instanceof Boolean) { - return positions.get(index).getBoolean(Position.KEY_MOTION); - } else { - return positions.get(index).getSpeed() > tripsConfig.getSpeedThreshold(); - } + return positions.get(index).getBoolean(Position.KEY_MOTION); } public Collection detectTripsAndStops( diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index b73ae7cc0..aecb1c4a4 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -57,6 +57,7 @@ public class ReportUtilsTest extends BaseTest { position.setTime(date(time)); position.setValid(true); position.setSpeed(speed); + position.set(Position.KEY_MOTION, speed > 0); position.set(Position.KEY_TOTAL_DISTANCE, totalDistance); return position; -- cgit v1.2.3 From 30d920c2e49c4022af8590c7d200907cde16d1c9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 7 Jul 2022 17:28:49 -0700 Subject: Decode Concox CRX1 serial --- .../java/org/traccar/protocol/Gt06ProtocolDecoder.java | 15 ++++++++++----- .../org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index c53fbfe5a..63210b2fa 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1004,11 +1004,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (subType == 0x1b) { - buf.readUnsignedByte(); // header - buf.readUnsignedByte(); // type - position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(4))); - buf.readUnsignedByte(); // checksum - buf.readUnsignedByte(); // footer + if (Character.isLetter(buf.getUnsignedByte(buf.readerIndex()))) { + String data = buf.readCharSequence(buf.readableBytes() - 6, StandardCharsets.US_ASCII).toString(); + position.set("serial", data.trim()); + } else { + buf.readUnsignedByte(); // header + buf.readUnsignedByte(); // type + position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(4))); + buf.readUnsignedByte(); // checksum + buf.readUnsignedByte(); // footer + } return position; } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 5b355e4f5..8c54fe3e4 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "79790019941b524649443a3030384642324245424133390d0a000c14930d0a"), + "serial", "RFID:008FB2BEBA39"); + verifyAttribute(decoder, binary( "7878241216040e102c22cf00915ffb04c6016300195a02d402283b00753f400571040001dda4880d0a"), Position.KEY_IGNITION, false); -- cgit v1.2.3 From 54d7f988b449fabbbd10fb123d63502d2427b43b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Jul 2022 09:21:39 -0700 Subject: Fix Galileo array decoding --- src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java | 3 +-- src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index bf14d47e0..0a57087fe 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -213,7 +213,6 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { buf.readSlice(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII)); break; case 0xea: - position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); break; default: diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java index d76fc5895..f9bdd6b42 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "011801018202130338363833343530333230343234323604640010a406207caa9f5b300c830a7901ca0ec802330000000034b802350540003e41703f422b1043234504004600e09000000000a000a100a200a300a400a500a600a700a800a900aa00ab00ac00ad00ae00af00b00000b10000b20000b30000b40000b50000b60000b70000b80000b90000c000000000c100000000c200000000c300000000c400c500c600c700c800c900ca00cb00cc00cd00ce00cf00d000d100d200d4d3140000d60000d70000d80000d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000f400000000f500000000f600000000f700000000f800000000f9000000008960")); + verifyPositions(decoder, binary( + "01bf83043200101ee4209832bc62300549589302511aaa013300002e00342e02350440003b41b15d42d50e4326450e0046040050000051000052fc5c5300006100008b009000000000d400000000e201000000e376000000e4efce0100e53b590200e600000000e773000000e800000000e9a002d007ea140000d6021b00f8430220ac760000000000000000043200101de4201232bc62300549589302511aaa013300002e00342e02350440012b41b55d42d40e4326450e0046040050000051000052145d5300006100008b009000000000d400000000e201000000e376000000e4efce0100e53b590200e600000000e773000000e800000000e9a002d007ea140000d6021b00f8430220ac760000000000000000043200101ce4208e2ebc62300549589302511aaa013300002e00342e02350440013b41a95d42cd0e4325450f0046040050000051000052235d5300006100008b009000000000d400000000e201000000e376000000e4efce0100e53b590200e600000000e773000000e802000000e9a002d007ea140000d6021b00f8430220ac760000000000000000043200101be4208b2ebc62300549589302511aaa013300002e00342e02350440013b41a45d42cd0e432545090046040050000051000052115d5300006100008b009000000000d400000000e201000000e375000000e48ac90100e53a590200e673000000e773000000e806000000e9a002d007ea140000d6021b00f8430220ac760000000000000000043200101ae420642ebc62300549589302511aaa013300002e00342e02350440013b419f5d42cd0e4324450b00460600500000519313521c5d5300006100008b009000000000d400000000e201000000e300000000e406000000e5c5580200e673000000e700000000e801000000e9a002d007ea140000d6021b00f8430220ac7600000000000000000432001019e420632ebc62300549589302511aaa013300002e00342e02350440013b41725d42cd0e4324450b0046060050000051ab1352035d5300006100008b009000000000d400000000e201000000e300000000e406000000e5c5580200e673000000e700000000e8d6021b00e9a002d007ea140000d6021b00f8430220ac7600000000000000000432001018e4205c2ebc62300549589302511aaa013300002e00342e02350440013b41955d42cd0e4324450a00460400500000510000520b5d5300006100008b009000000000d400000000e201000000e30d000000e4a4350000e5c5580200e600000000e700000000e8d6021b00e9a002d007ea140000d6021b00f8430220ac76000000000000000099f3")); + verifyPositions(decoder, binary( "017583018202120338363833343530333230363635373304520010384520c850975b300cc03a910107cbf9023365000607341300350640012a41236a4215104329450400460020500000510000520000530000540000550000c000000000c100000000c44bc500c6ffc700c800c900ca00cb00d4993b0500d64100d70000d8be02d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000018202120338363833343530333230363635373304520010394520c950975b300cab3a91010ecbf902336000be06341300350640012a41266a4216104329450400460020500000510000520000530000540000550000c000000000c100000000c44bc500c6ffc700c800c900ca00cb00d49b3b0500d64100d70000d8bc02d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f3000000000182021203383638333435303332303636353733045200103a4520ca50975b300c953a910113cbf9023358008f06341300350640012a41206a4215104329450400460020500000510000520000530000540000550000c000000000c100000000c44bc500c6ffc700c800c900ca00cb00d49e3b0500d64100d70000d8ba02d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f3000000000182021203383638333435303332303636353733045200103b45204251975b300c6d3a91011dcbf9023300008a06341300350640013a41726a4216104329450400460020500000510000520000530000540000550000c000000000c100000000c44bc500c6ffc700c800c900ca00cb00d4a33b0500d64800d70000d80003d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f3000000000182021203383638333435303332303636353733045200103c4520bb51975b300c6d3a91011dcbf9023300008a06341300350640013a41816a4216104329450400460020500000510000520000530000540000550000c000000000c100000000c44bc500c6ffc700c800c900ca00cb00d4a33b0500d64800d70000d80003d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000e007")); -- cgit v1.2.3 From eec839e7f47843629b4c730c765bb7605f50532e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Jul 2022 10:26:44 -0700 Subject: Support SR411 mini variant --- .../java/org/traccar/protocol/Gt06ProtocolDecoder.java | 15 +++++++++++++++ .../org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 18 insertions(+) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 63210b2fa..b65e4a4b8 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -112,6 +112,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { private enum Variant { VXT01, WANWAY_S20, + SR411_MINI, GT06E_CARD, BENWAY, S5, @@ -646,6 +647,18 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_LBS_MULTIPLE_3 && variant == Variant.SR411_MINI) { + + decodeGps(position, buf, false, deviceSession.get(DeviceSession.KEY_TIMEZONE)); + + decodeLbs(position, buf, type, false); + + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + + return position; + } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_MULTIPLE_3 || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI || type == MSG_LBS_2 || type == MSG_WIFI_3 || type == MSG_WIFI_5) { @@ -1323,6 +1336,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.VXT01; } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x31) { variant = Variant.WANWAY_S20; + } else if (header == 0x7878 && type == MSG_LBS_MULTIPLE_3 && length == 0x2e) { + variant = Variant.SR411_MINI; } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length >= 0x71) { variant = Variant.GT06E_CARD; } else if (header == 0x7878 && type == MSG_GPS_LBS_1 && length == 0x21) { diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 8c54fe3e4..f3f47a104 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyPosition(decoder, binary( + "78782e2416061a103600c80275298404a0a24000184602d4023a49006f060104ed01940000086508004139765000be7d640d0a")); + verifyAttribute(decoder, binary( "79790019941b524649443a3030384642324245424133390d0a000c14930d0a"), "serial", "RFID:008FB2BEBA39"); -- cgit v1.2.3 From b9d78159d736391ca2602d77fc8dbea358e89e59 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Jul 2022 15:22:55 -0700 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 8ce916432..8ba907843 100644 --- a/build.gradle +++ b/build.gradle @@ -97,7 +97,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.0", + "Implementation-Version": "5.1", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 64137f8d6..32d1846f5 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.0 +AppVersion=5.1 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index 77100dd32..ecdc4a407 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.0", + "version": "5.1", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From e3c98044a2deba5ea6ece533cfe860e03e985fb9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Jul 2022 16:03:42 -0700 Subject: Fix decoder injection --- src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java | 10 +++++++++- src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java index 68a70c944..361eeeef2 100644 --- a/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,13 @@ */ package org.traccar.protocol; +import com.google.inject.Injector; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; +import javax.inject.Inject; import java.net.SocketAddress; public class ArnaviProtocolDecoder extends BaseProtocolDecoder { @@ -33,6 +35,12 @@ public class ArnaviProtocolDecoder extends BaseProtocolDecoder { binaryProtocolDecoder = new ArnaviBinaryProtocolDecoder(protocol); } + @Inject + public void setInjector(Injector injector) { + injector.injectMembers(textProtocolDecoder); + injector.injectMembers(binaryProtocolDecoder); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { diff --git a/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java index ca1df7a13..a9736c9e7 100644 --- a/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,14 @@ */ package org.traccar.protocol; +import com.google.inject.Injector; import org.traccar.BaseProtocolDecoder; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.Protocol; +import javax.inject.Inject; import java.net.SocketAddress; public class Gl200ProtocolDecoder extends BaseProtocolDecoder { @@ -34,6 +36,12 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { binaryProtocolDecoder = new Gl200BinaryProtocolDecoder(protocol); } + @Inject + public void setInjector(Injector injector) { + injector.injectMembers(textProtocolDecoder); + injector.injectMembers(binaryProtocolDecoder); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { -- cgit v1.2.3 From 80b3af98806f9e837f65e8074882a97b22d65427 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Jul 2022 16:13:23 -0700 Subject: Sequence integration tests --- tools/test-integration.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tools/test-integration.py b/tools/test-integration.py index 6251b0d97..e49648cb6 100755 --- a/tools/test-integration.py +++ b/tools/test-integration.py @@ -142,7 +142,7 @@ def send_message(port, message): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', port)) s.send(message) - time.sleep(5) + time.sleep(0.5) s.close() def get_protocols(cookie, device_id): @@ -178,14 +178,8 @@ if __name__ == "__main__": print 'Missing: %d' % len(all - protocols) print 'Covered: %d' % len(protocols) - #if all - protocols: - # print '\nMissing: %s\n' % repr(list((all - protocols))) - for protocol in messages: - thread = threading.Thread(target = send_message, args = (ports[protocol], messages[protocol])) - thread.start() - - time.sleep(10) + send_message(ports[protocol], messages[protocol]) for device in devices: protocols -= set(get_protocols(cookie, devices[device])) -- cgit v1.2.3 From 6bf82f7e29e78c9ef4eab22530749991f420b2aa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Jul 2022 16:56:36 -0700 Subject: Filter null unique ids --- src/main/java/org/traccar/protocol/WialonProtocolDecoder.java | 2 +- src/main/java/org/traccar/session/ConnectionManager.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 8dd7aab24..3d57525b7 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -39,7 +39,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } private static final Pattern PATTERN_ANY = new PatternBuilder() - .expression("([^#]*)?") // imei + .expression("([^#]+)?") // imei .text("#") // start byte .expression("([^#]+)") // type .text("#") // separator diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index abc13988d..ad02c591b 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -47,11 +47,13 @@ import javax.inject.Inject; import javax.inject.Singleton; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -114,6 +116,8 @@ public class ConnectionManager implements BroadcastInterface { Endpoint endpoint = new Endpoint(channel, remoteAddress); Map endpointSessions = sessionsByEndpoint.getOrDefault( endpoint, new ConcurrentHashMap<>()); + + uniqueIds = Arrays.stream(uniqueIds).filter(Objects::nonNull).toArray(String[]::new); if (uniqueIds.length > 0) { for (String uniqueId : uniqueIds) { DeviceSession deviceSession = endpointSessions.get(uniqueId); -- cgit v1.2.3 From 15ff944349b44ead4d711459d7d0e54838c7f30c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 9 Jul 2022 17:40:06 -0700 Subject: Update submodule commit --- traccar-web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traccar-web b/traccar-web index d6445273b..97ee71bbf 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit d6445273b78fef8e5a081402f6ca6eb69ea952b2 +Subproject commit 97ee71bbfc9edd8ac15da97c0c4eb4f2b8aa8080 -- cgit v1.2.3 From 65cb239b78d3e75db565309b0196378e29a439d4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 10 Jul 2022 10:25:25 -0700 Subject: Specify multicast interface --- .../broadcast/MulticastBroadcastService.java | 22 ++++++++++++++++------ src/main/java/org/traccar/config/Keys.java | 7 +++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index 81b6cd5ec..877008eda 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -30,7 +30,9 @@ import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.MulticastSocket; +import java.net.NetworkInterface; import java.nio.charset.StandardCharsets; import java.util.HashSet; import java.util.Map; @@ -44,8 +46,9 @@ public class MulticastBroadcastService implements BroadcastService { private final ObjectMapper objectMapper; - private final InetAddress address; + private final NetworkInterface networkInterface; private final int port; + private final InetSocketAddress group; private DatagramSocket publisherSocket; @@ -56,8 +59,15 @@ public class MulticastBroadcastService implements BroadcastService { public MulticastBroadcastService(Config config, ObjectMapper objectMapper) throws IOException { this.objectMapper = objectMapper; - address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); port = config.getInteger(Keys.BROADCAST_PORT); + String interfaceName = config.getString(Keys.BROADCAST_INTERFACE); + if (interfaceName.indexOf('.') >= 0 || interfaceName.indexOf(':') >= 0) { + networkInterface = NetworkInterface.getByInetAddress(InetAddress.getByName(interfaceName)); + } else { + networkInterface = NetworkInterface.getByName(interfaceName); + } + InetAddress address = InetAddress.getByName(config.getString(Keys.BROADCAST_ADDRESS)); + group = new InetSocketAddress(address, port); } @Override @@ -106,7 +116,7 @@ public class MulticastBroadcastService implements BroadcastService { private void sendMessage(BroadcastMessage message) { try { byte[] buffer = objectMapper.writeValueAsString(message).getBytes(StandardCharsets.UTF_8); - DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port); + DatagramPacket packet = new DatagramPacket(buffer, buffer.length, group); publisherSocket.send(packet); } catch (IOException e) { LOGGER.warn("Broadcast failed", e); @@ -150,11 +160,10 @@ public class MulticastBroadcastService implements BroadcastService { } private final Runnable receiver = new Runnable() { - @SuppressWarnings("deprecation") @Override public void run() { try (MulticastSocket socket = new MulticastSocket(port)) { - socket.joinGroup(address); + socket.joinGroup(group, networkInterface); while (!service.isShutdown()) { DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); socket.receive(packet); @@ -162,10 +171,11 @@ public class MulticastBroadcastService implements BroadcastService { LOGGER.info("Broadcast received: {}", data); handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); } - socket.leaveGroup(address); + socket.leaveGroup(group, networkInterface); } catch (IOException e) { throw new RuntimeException(e); } } }; + } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 8e11b4013..6f19ee863 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1444,6 +1444,13 @@ public final class Keys { List.of(KeyType.CONFIG), "time,position,speed,course,accuracy,result"); + /** + * Multicast interface. It can be either an IP address or an interface name. + */ + public static final ConfigKey BROADCAST_INTERFACE = new StringConfigKey( + "broadcast.interface", + List.of(KeyType.CONFIG)); + /** * Multicast address for broadcasting synchronization events. */ -- cgit v1.2.3 From e5fed94589cff4614b248cb3408397febc0b1be7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Jul 2022 07:20:34 -0700 Subject: Use same socket for sending --- src/main/java/org/traccar/broadcast/MulticastBroadcastService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index 877008eda..134bba797 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -150,12 +150,10 @@ public class MulticastBroadcastService implements BroadcastService { @Override public void start() throws IOException { service.submit(receiver); - publisherSocket = new DatagramSocket(); } @Override public void stop() { - publisherSocket.close(); service.shutdown(); } @@ -163,6 +161,7 @@ public class MulticastBroadcastService implements BroadcastService { @Override public void run() { try (MulticastSocket socket = new MulticastSocket(port)) { + publisherSocket = socket; socket.joinGroup(group, networkInterface); while (!service.isShutdown()) { DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); @@ -172,6 +171,7 @@ public class MulticastBroadcastService implements BroadcastService { handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); } socket.leaveGroup(group, networkInterface); + publisherSocket = null; } catch (IOException e) { throw new RuntimeException(e); } -- cgit v1.2.3 From 767a449904b3d154ded4c5facefc73d7e33650f1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Jul 2022 17:58:35 -0700 Subject: Interface for sending multicast --- src/main/java/org/traccar/broadcast/MulticastBroadcastService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index 134bba797..c4ba0e059 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -161,17 +161,17 @@ public class MulticastBroadcastService implements BroadcastService { @Override public void run() { try (MulticastSocket socket = new MulticastSocket(port)) { - publisherSocket = socket; + socket.setNetworkInterface(networkInterface); socket.joinGroup(group, networkInterface); + publisherSocket = socket; while (!service.isShutdown()) { DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); socket.receive(packet); String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); - LOGGER.info("Broadcast received: {}", data); handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); } - socket.leaveGroup(group, networkInterface); publisherSocket = null; + socket.leaveGroup(group, networkInterface); } catch (IOException e) { throw new RuntimeException(e); } -- cgit v1.2.3 From 42140ceae97b3da66a54b0b5480242adf0b4e23e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Jul 2022 20:34:34 -0700 Subject: Simplify timeout units --- src/main/java/org/traccar/session/ConnectionManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index ad02c591b..d4bb9b4b1 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -100,7 +100,7 @@ public class ConnectionManager implements BroadcastInterface { this.timer = timer; this.broadcastService = broadcastService; this.deviceLookupService = deviceLookupService; - deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT) * 1000; + deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT); updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); broadcastService.registerListener(this); } @@ -270,7 +270,7 @@ public class ConnectionManager implements BroadcastInterface { if (!timeout1.isCancelled()) { deviceUnknown(deviceId); } - }, deviceTimeout, TimeUnit.MILLISECONDS)); + }, deviceTimeout, TimeUnit.SECONDS)); } try { -- cgit v1.2.3 From 7ccffa266e87badbbcfde73db86216fd4c667f35 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Jul 2022 20:35:07 -0700 Subject: Fix offline notifications (fix #4889) --- .../java/org/traccar/database/NotificationManager.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 1314a3d0a..ecb44b1d4 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -99,15 +99,13 @@ public class NotificationManager { notifications.forEach(notification -> { cacheManager.getNotificationUsers(notification.getId()).forEach(user -> { - new Thread(() -> { - for (String notificator : notification.getNotificatorsTypes()) { - try { - notificatorManager.getNotificator(notificator).send(user, event, position); - } catch (MessageException | InterruptedException exception) { - LOGGER.warn("Notification failed", exception); - } + for (String notificator : notification.getNotificatorsTypes()) { + try { + notificatorManager.getNotificator(notificator).send(user, event, position); + } catch (MessageException | InterruptedException exception) { + LOGGER.warn("Notification failed", exception); } - }).start(); + } }); }); } -- cgit v1.2.3 From 3f46f759c24746ddd2b8cd05cfc6cb99d5f7fd48 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Jul 2022 11:06:22 -0700 Subject: Filter notifications by device access (fix #4888) --- src/main/java/org/traccar/database/NotificationManager.java | 2 +- src/main/java/org/traccar/session/cache/CacheManager.java | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index ecb44b1d4..5be627f2a 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -98,7 +98,7 @@ public class NotificationManager { } notifications.forEach(notification -> { - cacheManager.getNotificationUsers(notification.getId()).forEach(user -> { + cacheManager.getNotificationUsers(notification.getId(), event.getDeviceId()).forEach(user -> { for (String notificator : notification.getNotificatorsTypes()) { try { notificatorManager.getNotificator(notificator).send(user, event, position); diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index cd71f5f9f..c1697faf9 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -123,10 +123,14 @@ public class CacheManager implements BroadcastInterface { } } - public List getNotificationUsers(long notificationId) { + public List getNotificationUsers(long notificationId, long deviceId) { try { lock.readLock().lock(); - return notificationUsers.get(notificationId); + var users = deviceLinks.get(deviceId).get(User.class).stream() + .collect(Collectors.toUnmodifiableSet()); + return notificationUsers.get(notificationId).stream() + .filter(user -> users.contains(user.getId())) + .collect(Collectors.toUnmodifiableList()); } finally { lock.readLock().unlock(); } -- cgit v1.2.3 From 98e2db95f73cb85a2623e2902741bcb4e73683e5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Jul 2022 16:50:26 -0700 Subject: Remove extended query annotation --- src/main/java/org/traccar/model/Device.java | 3 +-- src/main/java/org/traccar/model/User.java | 9 ++++---- .../java/org/traccar/storage/QueryExtended.java | 27 ---------------------- .../java/org/traccar/storage/query/Columns.java | 2 -- 4 files changed, 5 insertions(+), 36 deletions(-) delete mode 100644 src/main/java/org/traccar/storage/QueryExtended.java diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 219f078ed..35eb757f2 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -18,7 +18,6 @@ package org.traccar.model; import java.util.Date; import java.util.List; -import org.traccar.storage.QueryExtended; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @@ -67,7 +66,7 @@ public class Device extends GroupedModel { return this.lastUpdate; } - @QueryExtended + @QueryIgnore public void setLastUpdate(Date lastUpdate) { this.lastUpdate = lastUpdate; } diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 12fd03d45..9dd84ad14 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -17,7 +17,6 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnore; -import org.traccar.storage.QueryExtended; import org.traccar.storage.QueryIgnore; import org.traccar.helper.Hashing; import org.traccar.storage.StorageName; @@ -271,12 +270,12 @@ public class User extends ExtendedModel implements UserRestrictions { private String hashedPassword; @JsonIgnore - @QueryExtended + @QueryIgnore public String getHashedPassword() { return hashedPassword; } - @QueryExtended + @QueryIgnore public void setHashedPassword(String hashedPassword) { this.hashedPassword = hashedPassword; } @@ -284,12 +283,12 @@ public class User extends ExtendedModel implements UserRestrictions { private String salt; @JsonIgnore - @QueryExtended + @QueryIgnore public String getSalt() { return salt; } - @QueryExtended + @QueryIgnore public void setSalt(String salt) { this.salt = salt; } diff --git a/src/main/java/org/traccar/storage/QueryExtended.java b/src/main/java/org/traccar/storage/QueryExtended.java deleted file mode 100644 index 3796f1f40..000000000 --- a/src/main/java/org/traccar/storage/QueryExtended.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.storage; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface QueryExtended { -} diff --git a/src/main/java/org/traccar/storage/query/Columns.java b/src/main/java/org/traccar/storage/query/Columns.java index 97ca13be9..545995b3c 100644 --- a/src/main/java/org/traccar/storage/query/Columns.java +++ b/src/main/java/org/traccar/storage/query/Columns.java @@ -15,7 +15,6 @@ */ package org.traccar.storage.query; -import org.traccar.storage.QueryExtended; import org.traccar.storage.QueryIgnore; import java.lang.reflect.Method; @@ -36,7 +35,6 @@ public abstract class Columns { int parameterCount = type.equals("set") ? 1 : 0; if (method.getName().startsWith(type) && method.getParameterTypes().length == parameterCount && !method.isAnnotationPresent(QueryIgnore.class) - && !method.isAnnotationPresent(QueryExtended.class) && !method.getName().equals("getClass")) { columns.add(method.getName().substring(3).toLowerCase()); } -- cgit v1.2.3 From 493ff1068ea3e4d96f2475234b265b47cce8691f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Jul 2022 17:31:36 -0700 Subject: Persist device status (fix #4890, fix #4891) --- schema/changelog-5.2.xml | 21 +++++++++++++++++++++ schema/changelog-master.xml | 1 + .../handler/events/GeofenceEventHandler.java | 21 +++++++++++++++++++-- src/main/java/org/traccar/model/Device.java | 4 +--- .../java/org/traccar/session/ConnectionManager.java | 13 +++++++------ .../org/traccar/session/cache/CacheManager.java | 14 -------------- 6 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 schema/changelog-5.2.xml diff --git a/schema/changelog-5.2.xml b/schema/changelog-5.2.xml new file mode 100644 index 000000000..1ac9eedc5 --- /dev/null +++ b/schema/changelog-5.2.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index 471b0fe5d..83a1ac865 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -32,5 +32,6 @@ + diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index ca3fc3f89..70bdb84cb 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -26,6 +26,11 @@ import org.traccar.model.Geofence; import org.traccar.model.Position; import org.traccar.session.ConnectionManager; import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.ArrayList; @@ -39,12 +44,15 @@ public class GeofenceEventHandler extends BaseEventHandler { private final Config config; private final CacheManager cacheManager; private final ConnectionManager connectionManager; + private final Storage storage; @Inject - public GeofenceEventHandler(Config config, CacheManager cacheManager, ConnectionManager connectionManager) { + public GeofenceEventHandler( + Config config, CacheManager cacheManager, ConnectionManager connectionManager, Storage storage) { this.config = config; this.cacheManager = cacheManager; this.connectionManager = connectionManager; + this.storage = storage; } @Override @@ -66,8 +74,17 @@ public class GeofenceEventHandler extends BaseEventHandler { newGeofences.removeAll(oldGeofences); oldGeofences.removeAll(currentGeofences); - device.setGeofenceIds(currentGeofences); + if (!oldGeofences.isEmpty() || !newGeofences.isEmpty()) { + device.setGeofenceIds(currentGeofences.isEmpty() ? null : currentGeofences); + + try { + storage.updateObject(device, new Request( + new Columns.Include("geofenceIds"), new Condition.Equals("id", "id"))); + } catch (StorageException e) { + throw new RuntimeException("Update device geofences error", e); + } + connectionManager.updateDevice(true, device); } diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 35eb757f2..6593c59b0 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -50,14 +50,13 @@ public class Device extends GroupedModel { private String status; - @QueryIgnore public String getStatus() { return status != null ? status : STATUS_OFFLINE; } @QueryIgnore public void setStatus(String status) { - this.status = status; + this.status = status.trim(); } private Date lastUpdate; @@ -85,7 +84,6 @@ public class Device extends GroupedModel { private List geofenceIds; - @QueryIgnore public List getGeofenceIds() { return geofenceIds; } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index d4bb9b4b1..62fdd833b 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -52,6 +52,7 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -256,15 +257,15 @@ public class ConnectionManager implements BroadcastInterface { notificationManager.updateEvents(events); } + if (time != null) { + device.setLastUpdate(time); + } + Timeout timeout = timeouts.remove(deviceId); if (timeout != null) { timeout.cancel(); } - if (time != null) { - device.setLastUpdate(time); - } - if (status.equals(Device.STATUS_ONLINE)) { timeouts.put(deviceId, timer.newTimeout(timeout1 -> { if (!timeout1.isCancelled()) { @@ -275,7 +276,7 @@ public class ConnectionManager implements BroadcastInterface { try { storage.updateObject(device, new Request( - new Columns.Include("lastUpdate"), + new Columns.Include("status", "lastUpdate"), new Condition.Equals("id", "id"))); } catch (StorageException e) { LOGGER.warn("Update device status error", e); @@ -368,7 +369,7 @@ public class ConnectionManager implements BroadcastInterface { if (clazz1.equals(User.class) && clazz2.equals(Device.class)) { if (listeners.containsKey(id1)) { userDevices.get(id1).add(id2); - deviceUsers.put(id2, Set.of(id1)); + deviceUsers.put(id2, new HashSet<>(List.of(id1))); } } } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index c1697faf9..4e99161dd 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -18,7 +18,6 @@ package org.traccar.session.cache; import org.traccar.broadcast.BroadcastInterface; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; -import org.traccar.helper.model.GeofenceUtil; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -224,10 +223,6 @@ public class CacheManager implements BroadcastInterface { } finally { lock.writeLock().unlock(); } - - if (object instanceof Device) { - invalidateDeviceGeofences((Device) object); - } } } @@ -304,8 +299,6 @@ public class CacheManager implements BroadcastInterface { devicePositions.put(deviceId, storage.getObject(Position.class, new Request( new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); } - - invalidateDeviceGeofences(device); } } @@ -359,11 +352,4 @@ public class CacheManager implements BroadcastInterface { } } - private void invalidateDeviceGeofences(Device device) { - Position position = getPosition(device.getId()); - if (position != null) { - device.setGeofenceIds(GeofenceUtil.getCurrentGeofences(config, this, position)); - } - } - } -- cgit v1.2.3 From a1ec223a7ee9ff86a881428f787c6f11d532432a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Jul 2022 20:13:45 -0700 Subject: Support from email name (fix #4887) --- src/main/java/org/traccar/database/MailManager.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index 0c868e1fc..72b8b72c1 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -31,6 +31,7 @@ import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; +import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.Properties; @@ -88,6 +89,10 @@ public final class MailManager { if (from != null) { properties.put("mail.smtp.from", from); } + String fromName = provider.getString("mail.smtp.fromName"); + if (fromName != null) { + properties.put("mail.smtp.fromName", fromName); + } } return properties; } @@ -120,7 +125,16 @@ public final class MailManager { String from = properties.getProperty("mail.smtp.from"); if (from != null) { - message.setFrom(new InternetAddress(from)); + String fromName = properties.getProperty("mail.smtp.fromName"); + if (fromName != null) { + try { + message.setFrom(new InternetAddress(from, fromName)); + } catch (UnsupportedEncodingException e) { + throw new MessagingException("Email address issue"); + } + } else { + message.setFrom(new InternetAddress(from)); + } } message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); -- cgit v1.2.3 From 859b9d4aad68f4dafdee60ff14d3c9c0b32693a0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 07:18:16 -0700 Subject: Ignore own multicast packets --- debug.xml | 5 +++-- src/main/java/org/traccar/broadcast/MulticastBroadcastService.java | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/debug.xml b/debug.xml index debbd06b7..a597d83c5 100644 --- a/debug.xml +++ b/debug.xml @@ -24,7 +24,8 @@ true 6037 - + diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index c4ba0e059..be24989dd 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -167,8 +167,10 @@ public class MulticastBroadcastService implements BroadcastService { while (!service.isShutdown()) { DatagramPacket packet = new DatagramPacket(receiverBuffer, receiverBuffer.length); socket.receive(packet); - String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); - handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); + if (networkInterface.inetAddresses().noneMatch(a -> a.equals(packet.getAddress()))) { + String data = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); + handleMessage(objectMapper.readValue(data, BroadcastMessage.class)); + } } publisherSocket = null; socket.leaveGroup(group, networkInterface); -- cgit v1.2.3 From adbeacc62ecb91c94f6cfe7dea8e79b8f5e1c802 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 08:05:10 -0700 Subject: Fix geofenceIds issue (fix #4890) --- src/main/java/org/traccar/model/Device.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 6593c59b0..501c7e1c0 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -17,6 +17,7 @@ package org.traccar.model; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @@ -89,8 +90,8 @@ public class Device extends GroupedModel { } @QueryIgnore - public void setGeofenceIds(List geofenceIds) { - this.geofenceIds = geofenceIds; + public void setGeofenceIds(List geofenceIds) { + this.geofenceIds = geofenceIds.stream().map(Number::longValue).collect(Collectors.toList()); } private String phone; -- cgit v1.2.3 From 33733f835e88a62c4a5259ab330723b88037adf1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 09:39:22 -0700 Subject: Simplify attribute check --- src/main/java/org/traccar/BaseProtocolEncoder.java | 2 +- src/main/java/org/traccar/WebDataHandler.java | 2 +- src/main/java/org/traccar/handler/CopyAttributesHandler.java | 3 +-- src/main/java/org/traccar/handler/DistanceHandler.java | 4 ++-- src/main/java/org/traccar/handler/EngineHoursHandler.java | 2 +- src/main/java/org/traccar/handler/FilterHandler.java | 4 ++-- src/main/java/org/traccar/handler/MotionHandler.java | 2 +- src/main/java/org/traccar/handler/events/FuelDropEventHandler.java | 4 ++-- src/main/java/org/traccar/handler/events/IgnitionEventHandler.java | 4 ++-- src/main/java/org/traccar/handler/events/MotionEventHandler.java | 2 +- src/main/java/org/traccar/model/ExtendedModel.java | 4 ++++ src/main/java/org/traccar/notificators/NotificatorFirebase.java | 2 +- src/main/java/org/traccar/notificators/NotificatorPushover.java | 2 +- src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java | 2 +- src/main/java/org/traccar/protocol/S168ProtocolDecoder.java | 2 +- src/main/java/org/traccar/reports/SummaryReportProvider.java | 3 +-- src/main/java/org/traccar/reports/common/ReportUtils.java | 7 +++---- 18 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index bc1180a08..9c3934184 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -61,7 +61,7 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter } protected void initDevicePassword(Command command, String defaultPassword) { - if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { + if (!command.hasAttribute(Command.KEY_DEVICE_PASSWORD)) { String password = AttributeUtil.getDevicePassword( cacheManager, command.getDeviceId(), getProtocolName(), defaultPassword); command.set(Command.KEY_DEVICE_PASSWORD, password); diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index d25c4fd3c..d0aa32e53 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -125,7 +125,7 @@ public class WebDataHandler extends BaseDataHandler { } private String calculateStatus(Position position) { - if (position.getAttributes().containsKey(Position.KEY_ALARM)) { + if (position.hasAttribute(Position.KEY_ALARM)) { return "0xF841"; // STATUS_PANIC_ON } else if (position.getSpeed() < 1.0) { return "0xF020"; // STATUS_LOCATION diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index 50d36471a..1fa47cfaa 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -46,8 +46,7 @@ public class CopyAttributesHandler extends BaseDataHandler { Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null && attributesString != null) { for (String attribute : attributesString.split("[ ,]")) { - if (last.getAttributes().containsKey(attribute) - && !position.getAttributes().containsKey(attribute)) { + if (last.hasAttribute(attribute) && !position.hasAttribute(attribute)) { position.getAttributes().put(attribute, last.getAttributes().get(attribute)); } } diff --git a/src/main/java/org/traccar/handler/DistanceHandler.java b/src/main/java/org/traccar/handler/DistanceHandler.java index fb82b5d8e..87c4a81c9 100644 --- a/src/main/java/org/traccar/handler/DistanceHandler.java +++ b/src/main/java/org/traccar/handler/DistanceHandler.java @@ -49,7 +49,7 @@ public class DistanceHandler extends BaseDataHandler { protected Position handlePosition(Position position) { double distance = 0.0; - if (position.getAttributes().containsKey(Position.KEY_DISTANCE)) { + if (position.hasAttribute(Position.KEY_DISTANCE)) { distance = position.getDouble(Position.KEY_DISTANCE); } double totalDistance = 0.0; @@ -57,7 +57,7 @@ public class DistanceHandler extends BaseDataHandler { Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { totalDistance = last.getDouble(Position.KEY_TOTAL_DISTANCE); - if (!position.getAttributes().containsKey(Position.KEY_DISTANCE)) { + if (!position.hasAttribute(Position.KEY_DISTANCE)) { distance = DistanceCalculator.distance( position.getLatitude(), position.getLongitude(), last.getLatitude(), last.getLongitude()); diff --git a/src/main/java/org/traccar/handler/EngineHoursHandler.java b/src/main/java/org/traccar/handler/EngineHoursHandler.java index bfffdcb0c..54a1a0c25 100644 --- a/src/main/java/org/traccar/handler/EngineHoursHandler.java +++ b/src/main/java/org/traccar/handler/EngineHoursHandler.java @@ -35,7 +35,7 @@ public class EngineHoursHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - if (!position.getAttributes().containsKey(Position.KEY_HOURS)) { + if (!position.hasAttribute(Position.KEY_HOURS)) { Position last = cacheManager.getPosition(position.getDeviceId()); if (last != null) { long hours = last.getLong(Position.KEY_HOURS); diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 00cbf92a0..0bd57319a 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -103,7 +103,7 @@ public class FilterHandler extends BaseDataHandler { private boolean filterDuplicate(Position position, Position last) { if (filterDuplicate && last != null && position.getFixTime().equals(last.getFixTime())) { for (String key : position.getAttributes().keySet()) { - if (!last.getAttributes().containsKey(key)) { + if (!last.hasAttribute(key)) { return false; } } @@ -163,7 +163,7 @@ public class FilterHandler extends BaseDataHandler { if (skipAttributes) { String string = AttributeUtil.lookup(cacheManager, Keys.FILTER_SKIP_ATTRIBUTES, position.getDeviceId()); for (String attribute : string.split("[ ,]")) { - if (position.getAttributes().containsKey(attribute)) { + if (position.hasAttribute(attribute)) { return true; } } diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java index 7b2c04ecf..25ee615c5 100644 --- a/src/main/java/org/traccar/handler/MotionHandler.java +++ b/src/main/java/org/traccar/handler/MotionHandler.java @@ -35,7 +35,7 @@ public class MotionHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - if (!position.getAttributes().containsKey(Position.KEY_MOTION)) { + if (!position.hasAttribute(Position.KEY_MOTION)) { position.set(Position.KEY_MOTION, position.getSpeed() > speedThreshold); } return position; diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java index 2d105af3e..25ae1fadb 100644 --- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java @@ -53,8 +53,8 @@ public class FuelDropEventHandler extends BaseEventHandler { cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); if (fuelDropThreshold > 0) { Position lastPosition = cacheManager.getPosition(position.getDeviceId()); - if (position.getAttributes().containsKey(Position.KEY_FUEL_LEVEL) - && lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_FUEL_LEVEL)) { + if (position.hasAttribute(Position.KEY_FUEL_LEVEL) + && lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) { double drop = lastPosition.getDouble(Position.KEY_FUEL_LEVEL) - position.getDouble(Position.KEY_FUEL_LEVEL); diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java index 6e411539c..3c5ac3545 100644 --- a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java @@ -47,11 +47,11 @@ public class IgnitionEventHandler extends BaseEventHandler { Map result = null; - if (position.getAttributes().containsKey(Position.KEY_IGNITION)) { + if (position.hasAttribute(Position.KEY_IGNITION)) { boolean ignition = position.getBoolean(Position.KEY_IGNITION); Position lastPosition = cacheManager.getPosition(position.getDeviceId()); - if (lastPosition != null && lastPosition.getAttributes().containsKey(Position.KEY_IGNITION)) { + if (lastPosition != null && lastPosition.hasAttribute(Position.KEY_IGNITION)) { boolean oldIgnition = lastPosition.getBoolean(Position.KEY_IGNITION); if (ignition && !oldIgnition) { diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index bc9d5f722..1be1896ef 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -92,7 +92,7 @@ public class MotionEventHandler extends BaseEventHandler { double distance = PositionUtil.calculateDistance(motionPosition, position, false); Boolean ignition = null; if (tripsConfig.getUseIgnition() - && position.getAttributes().containsKey(Position.KEY_IGNITION)) { + && position.hasAttribute(Position.KEY_IGNITION)) { ignition = position.getBoolean(Position.KEY_IGNITION); } if (newMotion) { diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index 8353d0e66..0fa1856d1 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -22,6 +22,10 @@ public class ExtendedModel extends BaseModel { private Map attributes = new LinkedHashMap<>(); + public boolean hasAttribute(String key) { + return attributes.containsKey(key); + } + public Map getAttributes() { return attributes; } diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 5787b7ef2..17a6735ee 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -69,7 +69,7 @@ public class NotificatorFirebase implements Notificator { @Override public void send(User user, Event event, Position position) { - if (user.getAttributes().containsKey("notificationTokens")) { + if (user.hasAttribute("notificationTokens")) { var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 32ceae780..671984f86 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -65,7 +65,7 @@ public class NotificatorPushover implements Notificator { public void send(User user, Event event, Position position) { String device = ""; - if (user.getAttributes().containsKey("notificator.pushover.device")) { + if (user.hasAttribute("notificator.pushover.device")) { device = user.getString("notificator.pushover.device").replaceAll(" *, *", ","); } diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index 0a57087fe..d8a753abe 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -284,7 +284,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { if (hasLocation && position.getFixTime() != null) { positions.add(position); - } else if (position.getAttributes().containsKey(Position.KEY_RESULT)) { + } else if (position.hasAttribute(Position.KEY_RESULT)) { position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); positions.add(position); diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index a2009e1b2..b63bcd0c0 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -202,7 +202,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 1, Double.parseDouble(alarm.substring(2))); } else if (alarm.startsWith("oil ")) { position.set(Position.KEY_FUEL_LEVEL, Double.parseDouble(alarm.substring(4))); - } else if (!position.getAttributes().containsKey(Position.KEY_ALARM) && !alarm.equals("tracker")) { + } else if (!position.hasAttribute(Position.KEY_ALARM) && !alarm.equals("tracker")) { position.set(Position.KEY_EVENT, alarm); } diff --git a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java index a88bfa65a..cf665c6ba 100644 --- a/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/S168ProtocolDecoder.java @@ -107,7 +107,7 @@ public class S168ProtocolDecoder extends BaseProtocolDecoder { if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { position.setNetwork(network); } - if (!position.getAttributes().containsKey(Position.KEY_SATELLITES)) { + if (!position.hasAttribute(Position.KEY_SATELLITES)) { getLastLocation(position, null); } diff --git a/src/main/java/org/traccar/reports/SummaryReportProvider.java b/src/main/java/org/traccar/reports/SummaryReportProvider.java index 02033b9e5..9415f3e81 100644 --- a/src/main/java/org/traccar/reports/SummaryReportProvider.java +++ b/src/main/java/org/traccar/reports/SummaryReportProvider.java @@ -79,8 +79,7 @@ public class SummaryReportProvider { result.setSpentFuel(reportUtils.calculateFuel(firstPosition, previousPosition)); long durationMilliseconds; - if (firstPosition.getAttributes().containsKey(Position.KEY_HOURS) - && previousPosition.getAttributes().containsKey(Position.KEY_HOURS)) { + if (firstPosition.hasAttribute(Position.KEY_HOURS) && previousPosition.hasAttribute(Position.KEY_HOURS)) { durationMilliseconds = previousPosition.getLong(Position.KEY_HOURS) - firstPosition.getLong(Position.KEY_HOURS); result.setEngineHours(durationMilliseconds); diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index ce5e3d8d4..253a6a2b6 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -154,9 +154,9 @@ public class ReportUtils { } public String findDriver(Position firstPosition, Position lastPosition) { - if (firstPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { + if (firstPosition.hasAttribute(Position.KEY_DRIVER_UNIQUE_ID)) { return firstPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); - } else if (lastPosition.getAttributes().containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { + } else if (lastPosition.hasAttribute(Position.KEY_DRIVER_UNIQUE_ID)) { return lastPosition.getString(Position.KEY_DRIVER_UNIQUE_ID); } return null; @@ -298,8 +298,7 @@ public class ReportUtils { stop.setDuration(stopDuration); stop.setSpentFuel(calculateFuel(startStop, endStop)); - if (startStop.getAttributes().containsKey(Position.KEY_HOURS) - && endStop.getAttributes().containsKey(Position.KEY_HOURS)) { + if (startStop.hasAttribute(Position.KEY_HOURS) && endStop.hasAttribute(Position.KEY_HOURS)) { stop.setEngineHours(endStop.getLong(Position.KEY_HOURS) - startStop.getLong(Position.KEY_HOURS)); } -- cgit v1.2.3 From a8e38b74e5fc6789676bf35a9b92594a230e3ad8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 17:31:52 -0700 Subject: Avoid broadcast loops (fix #4894) --- src/main/java/org/traccar/api/BaseObjectResource.java | 6 +++--- .../org/traccar/api/resource/PermissionsResource.java | 2 ++ .../java/org/traccar/api/resource/ServerResource.java | 2 +- .../java/org/traccar/broadcast/BroadcastInterface.java | 3 ++- .../org/traccar/broadcast/MulticastBroadcastService.java | 5 ++++- src/main/java/org/traccar/session/ConnectionManager.java | 1 + src/main/java/org/traccar/session/cache/CacheManager.java | 15 ++++++++++----- 7 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index d10843917..2a3bbe239 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -71,8 +71,8 @@ public abstract class BaseObjectResource extends BaseResour entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); LogAction.create(getUserId(), entity); storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId())); - cacheManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); - connectionManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId()); + cacheManager.invalidatePermission(true, User.class, getUserId(), baseClass, entity.getId()); + connectionManager.invalidatePermission(true, User.class, getUserId(), baseClass, entity.getId()); LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId()); return Response.ok(entity).build(); @@ -98,7 +98,7 @@ public abstract class BaseObjectResource extends BaseResour storage.updateObject(entity, new Request( new Columns.Exclude("id"), new Condition.Equals("id", "id"))); - cacheManager.updateOrInvalidate(entity); + cacheManager.updateOrInvalidate(true, entity); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java index 44fc897ac..d35cb98bb 100644 --- a/src/main/java/org/traccar/api/resource/PermissionsResource.java +++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java @@ -72,6 +72,7 @@ public class PermissionsResource extends BaseResource { checkPermission(permission); storage.addPermission(permission); cacheManager.invalidatePermission( + true, permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.link(getUserId(), @@ -96,6 +97,7 @@ public class PermissionsResource extends BaseResource { checkPermission(permission); storage.removePermission(permission); cacheManager.invalidatePermission( + true, permission.getOwnerClass(), permission.getOwnerId(), permission.getPropertyClass(), permission.getPropertyId()); LogAction.unlink(getUserId(), diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 3e6792f5b..4fc76a0d7 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -77,7 +77,7 @@ public class ServerResource extends BaseResource { storage.updateObject(entity, new Request( new Columns.Exclude("id"), new Condition.Equals("id", "id"))); - cacheManager.updateOrInvalidate(entity); + cacheManager.updateOrInvalidate(true, entity); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); } diff --git a/src/main/java/org/traccar/broadcast/BroadcastInterface.java b/src/main/java/org/traccar/broadcast/BroadcastInterface.java index 69e610dc6..dddba68b6 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastInterface.java +++ b/src/main/java/org/traccar/broadcast/BroadcastInterface.java @@ -31,10 +31,11 @@ public interface BroadcastInterface { default void updateEvent(boolean local, long userId, Event event) { } - default void invalidateObject(Class clazz, long id) { + default void invalidateObject(boolean local, Class clazz, long id) { } default void invalidatePermission( + boolean local, Class clazz1, long id1, Class clazz2, long id2) { } diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index be24989dd..3eafe07d3 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -98,7 +98,7 @@ public class MulticastBroadcastService implements BroadcastService { } @Override - public void invalidateObject(Class clazz, long id) { + public void invalidateObject(boolean local, Class clazz, long id) { BroadcastMessage message = new BroadcastMessage(); message.setChanges(Map.of(Permission.getKey(clazz), id)); sendMessage(message); @@ -106,6 +106,7 @@ public class MulticastBroadcastService implements BroadcastService { @Override public void invalidatePermission( + boolean local, Class clazz1, long id1, Class clazz2, long id2) { BroadcastMessage message = new BroadcastMessage(); @@ -137,10 +138,12 @@ public class MulticastBroadcastService implements BroadcastService { if (iterator.hasNext()) { var second = iterator.next(); listeners.forEach(listener -> listener.invalidatePermission( + false, Permission.getKeyClass(first.getKey()), first.getValue(), Permission.getKeyClass(second.getKey()), second.getValue())); } else { listeners.forEach(listener -> listener.invalidateObject( + false, Permission.getKeyClass(first.getKey()), first.getValue())); } } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 62fdd833b..9888cca2b 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -364,6 +364,7 @@ public class ConnectionManager implements BroadcastInterface { @Override public synchronized void invalidatePermission( + boolean local, Class clazz1, long id1, Class clazz2, long id2) { if (clazz1.equals(User.class) && clazz2.equals(Device.class)) { diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 4e99161dd..58eb95327 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -188,12 +188,12 @@ public class CacheManager implements BroadcastInterface { } @Override - public void invalidateObject(Class clazz, long id) { + public void invalidateObject(boolean local, Class clazz, long id) { try { var object = storage.getObject(clazz, new Request( new Columns.All(), new Condition.Equals("id", "id", id))); if (object != null) { - updateOrInvalidate(object); + updateOrInvalidate(local, object); } else { invalidate(clazz, id); } @@ -202,8 +202,10 @@ public class CacheManager implements BroadcastInterface { } } - public void updateOrInvalidate(T object) throws StorageException { - broadcastService.invalidateObject(object.getClass(), object.getId()); + public void updateOrInvalidate(boolean local, T object) throws StorageException { + if (local) { + broadcastService.invalidateObject(true, object.getClass(), object.getId()); + } boolean invalidate = false; var before = getObject(object.getClass(), object.getId()); @@ -232,9 +234,12 @@ public class CacheManager implements BroadcastInterface { @Override public void invalidatePermission( + boolean local, Class clazz1, long id1, Class clazz2, long id2) { - broadcastService.invalidatePermission(clazz1, id1, clazz2, id2); + if (local) { + broadcastService.invalidatePermission(true, clazz1, id1, clazz2, id2); + } try { invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2)); -- cgit v1.2.3 From f20ab941671e2325140767da0d5c56187941b3e8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 17:39:09 -0700 Subject: Handle null status --- src/main/java/org/traccar/model/Device.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 501c7e1c0..f3debd1f2 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -57,7 +57,7 @@ public class Device extends GroupedModel { @QueryIgnore public void setStatus(String status) { - this.status = status.trim(); + this.status = status != null ? status.trim() : null; } private Date lastUpdate; -- cgit v1.2.3 From 92807c47464a840999716d2e732f569351deaea0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Jul 2022 20:41:20 -0700 Subject: Add more integration tests --- tools/test-integration.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/test-integration.py b/tools/test-integration.py index e49648cb6..42922147e 100755 --- a/tools/test-integration.py +++ b/tools/test-integration.py @@ -90,6 +90,15 @@ messages = { 'starlink' : '$SLU123456,06,622,170329035057,01,170329035057,+3158.0018,+03446.6968,004.9,007,000099,1,1,0,0,0,0,0,0,,,14.176,03.826,,1,1,1,4*B0\r\n', 'alematics' : '$T,50,592,123456789012345,20170515062915,20170515062915,25.035005,121.561555,0,31,89,3.7,5,1,0,0.000,12.752,1629,38,12752,4203,6\r\n', 'vtfms' : '(123456789012345,00I76,00,000,,,,,A,133755,210617,10.57354,077.24912,SW,000,00598,00000,K,0017368,1,12.7,,,0.000,,,0,0,0,0,1,1,0,,)074' + 'esky': 'ET;0;123456789012345;R;6+190317162511+41.32536+19.83144+0.14+0+0x0+0+18460312+0+1233+192', + 'genx': '123456789012345,08/31/2017 17:24:13,45.47275,-73.65491,5,19,117,1.14,147,ON,1462,0,6,N,0,0.000,-95.0,-1.0,0,0.0000,0.0000,0.000,0,0.00,0.00,0.00,NA,U,UUU,0,-95.0,U\r\n', + 'dway': 'AA55,115,1234,1,171024,195059,28.0153,-82.4761,3, 1.0,319,1000,0000,00000,4244,0,0,0,D\r\n', + 'oko': '{123456789012345,090745,A,4944.302,N,02353.366,E,0.0,225,251120,7,0.27,F9,11.3,1}', + 'ivt401': '(TLN,123456789012345,250118,063827,+18.598098,+73.806518,0,79,0,1,1,5,1200,0,0.0,11.50,4.00,36,0,0,1.00,0,0,12702,202,0);', + 't57': '*T57#F1#1234567890#301117#000843#2234.1303#N#08826.1714#E#+0.242,+0.109,-0.789#0.000#6.20000#A2#4.2#', + 'm2c': '[#M2C,2020,P1.B1.H1.F1.R1,101,123456789012345,2,L,1,100,170704,074933,28.647556,77.192940,900,194,0.0,0,0,0,255,11942,0,0,0,0,0,0,0,0,30068,5051,0,0,1*8159\r\n]', + 'cautela': '20,123456789012,14,02,18,16.816667,96.166667,1325,S,*2E\r\n', + 'pt60': '@B#@|01|001|123456789012345|9425010450971470|1|45|20181127122717|32.701093|35.570938|1|@R#@', } baseUrl = 'http://localhost:8082' -- cgit v1.2.3 From a9199ab710056dda371aa3dd25cffc225374c0d6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 08:09:16 -0700 Subject: Support AT20 protocol format --- .../java/org/traccar/protocol/TotemProtocolDecoder.java | 14 ++++++++++++-- .../org/traccar/protocol/TotemProtocolDecoderTest.java | 3 +++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 4f520f360..9d0d794f8 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -140,8 +140,12 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { .number("(x{8})") // status .number("(dd)(dd)(dd)") // date (yymmdd) .number("(dd)(dd)(dd)") // time (hhmmss) + .groupBegin() .number("(dd)") // battery .number("(dd)") // external power + .or() + .number("(ddd)") // battery + .groupEnd() .number("(dddd)") // adc 1 .groupBegin() .groupBegin() @@ -166,6 +170,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { .number("(d{7})") // odometer .number("(dd)(dd.dddd)([NS])") // latitude .number("(ddd)(dd.dddd)([EW])") // longitude + .number("dddd").optional() // temperature .number("dddd") // serial number .number("xx") // checksum .any() @@ -379,8 +384,13 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.setTime(parser.nextDateTime()); - position.set(Position.KEY_BATTERY, parser.nextDouble() * 0.1); - position.set(Position.KEY_POWER, parser.nextDouble()); + if (parser.hasNext(2)) { + position.set(Position.KEY_BATTERY, parser.nextDouble() * 0.1); + position.set(Position.KEY_POWER, parser.nextDouble()); + } + if (parser.hasNext()) { + position.set(Position.KEY_BATTERY, parser.nextDouble() * 0.01); + } position.set(Position.PREFIX_ADC + 1, parser.next()); position.set(Position.PREFIX_ADC + 2, parser.next()); diff --git a/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java index 83498b5ac..df5734568 100644 --- a/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TotemProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TotemProtocolDecoderTest extends ProtocolTest { var decoder = inject(new TotemProtocolDecoder(null)); + verifyPosition(decoder, text( + "$$0111AA353081090067318|0804400022070722520240400005B364ED5003107300001.700000002245.3919N10231.6952W000001860E")); + verifyPosition(decoder, text( "$$0112E5864606045334223|201112223514,-68.923106,-22.455926,$Cloud,1738,621,730,12100,0,0,255,0,40,40,0,0,255,|13")); -- cgit v1.2.3 From 34fefbffa49925a5d337ff388fb9db400d707f8b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 16:36:26 -0700 Subject: Null check geofenceIds (fix #4896) --- src/main/java/org/traccar/model/Device.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index f3debd1f2..57ba07624 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -91,7 +91,11 @@ public class Device extends GroupedModel { @QueryIgnore public void setGeofenceIds(List geofenceIds) { - this.geofenceIds = geofenceIds.stream().map(Number::longValue).collect(Collectors.toList()); + if (geofenceIds != null) { + this.geofenceIds = geofenceIds.stream().map(Number::longValue).collect(Collectors.toList()); + } else { + this.geofenceIds = null; + } } private String phone; -- cgit v1.2.3 From 0bd4c493e9003449457e87ebad6c7016ded71c8d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 17:00:57 -0700 Subject: Add LBS location caching (fix #3790) --- src/main/java/org/traccar/MainModule.java | 5 ++- src/main/java/org/traccar/config/Keys.java | 7 ++++ .../java/org/traccar/handler/GeocoderHandler.java | 8 ++-- .../org/traccar/handler/GeolocationHandler.java | 45 ++++++++++++++++------ src/main/java/org/traccar/model/CellTower.java | 20 ++++++++++ src/main/java/org/traccar/model/Network.java | 22 ++++++++++- .../java/org/traccar/model/WifiAccessPoint.java | 19 ++++++++- 7 files changed, 106 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index f60d41d62..b9543af25 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -256,9 +256,10 @@ public class MainModule extends AbstractModule { @Provides public static GeolocationHandler provideGeolocationHandler( - Config config, @Nullable GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) { + Config config, @Nullable GeolocationProvider geolocationProvider, CacheManager cacheManager, + StatisticsManager statisticsManager) { if (geolocationProvider != null) { - return new GeolocationHandler(config, geolocationProvider, statisticsManager); + return new GeolocationHandler(config, geolocationProvider, cacheManager, statisticsManager); } return null; } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 6f19ee863..2e1a14eaf 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1293,6 +1293,13 @@ public final class Keys { "geolocation.processInvalidPositions", List.of(KeyType.CONFIG)); + /** + * Reuse last geolocation result if network details have not changed. + */ + public static final ConfigKey GEOLOCATION_REUSE = new BooleanConfigKey( + "geolocation.reuse", + List.of(KeyType.CONFIG)); + /** * Default MCC value to use if device doesn't report MCC. */ diff --git a/src/main/java/org/traccar/handler/GeocoderHandler.java b/src/main/java/org/traccar/handler/GeocoderHandler.java index 0248fca05..e4f240a90 100644 --- a/src/main/java/org/traccar/handler/GeocoderHandler.java +++ b/src/main/java/org/traccar/handler/GeocoderHandler.java @@ -35,14 +35,14 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { private final CacheManager cacheManager; private final boolean ignorePositions; private final boolean processInvalidPositions; - private final int geocoderReuseDistance; + private final int reuseDistance; public GeocoderHandler(Config config, Geocoder geocoder, CacheManager cacheManager) { this.geocoder = geocoder; this.cacheManager = cacheManager; ignorePositions = config.getBoolean(Keys.GEOCODER_IGNORE_POSITIONS); processInvalidPositions = config.getBoolean(Keys.GEOCODER_PROCESS_INVALID_POSITIONS); - geocoderReuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0); + reuseDistance = config.getInteger(Keys.GEOCODER_REUSE_DISTANCE, 0); } @Override @@ -50,10 +50,10 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { if (message instanceof Position && !ignorePositions) { final Position position = (Position) message; if (processInvalidPositions || position.getValid()) { - if (geocoderReuseDistance != 0) { + if (reuseDistance != 0) { Position lastPosition = cacheManager.getPosition(position.getDeviceId()); if (lastPosition != null && lastPosition.getAddress() != null - && position.getDouble(Position.KEY_DISTANCE) <= geocoderReuseDistance) { + && position.getDouble(Position.KEY_DISTANCE) <= reuseDistance) { position.setAddress(lastPosition.getAddress()); ctx.fireChannelRead(position); return; diff --git a/src/main/java/org/traccar/handler/GeolocationHandler.java b/src/main/java/org/traccar/handler/GeolocationHandler.java index 0e78322c8..e7389f22d 100644 --- a/src/main/java/org/traccar/handler/GeolocationHandler.java +++ b/src/main/java/org/traccar/handler/GeolocationHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,6 +25,7 @@ import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; import org.traccar.geolocation.GeolocationProvider; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; @ChannelHandler.Sharable public class GeolocationHandler extends ChannelInboundHandlerAdapter { @@ -32,14 +33,19 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(GeolocationHandler.class); private final GeolocationProvider geolocationProvider; + private final CacheManager cacheManager; private final StatisticsManager statisticsManager; private final boolean processInvalidPositions; + private final boolean reuse; public GeolocationHandler( - Config config, GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) { + Config config, GeolocationProvider geolocationProvider, CacheManager cacheManager, + StatisticsManager statisticsManager) { this.geolocationProvider = geolocationProvider; + this.cacheManager = cacheManager; this.statisticsManager = statisticsManager; - this.processInvalidPositions = config.getBoolean(Keys.GEOLOCATION_PROCESS_INVALID_POSITIONS); + processInvalidPositions = config.getBoolean(Keys.GEOLOCATION_PROCESS_INVALID_POSITIONS); + reuse = config.getBoolean(Keys.GEOLOCATION_REUSE); } @Override @@ -48,6 +54,17 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter { final Position position = (Position) message; if ((position.getOutdated() || processInvalidPositions && !position.getValid()) && position.getNetwork() != null) { + if (reuse) { + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + if (lastPosition != null && position.getNetwork().equals(lastPosition.getNetwork())) { + updatePosition( + position, lastPosition.getLatitude(), lastPosition.getLongitude(), + lastPosition.getAccuracy()); + ctx.fireChannelRead(position); + return; + } + } + if (statisticsManager != null) { statisticsManager.registerGeolocationRequest(); } @@ -56,15 +73,7 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter { new GeolocationProvider.LocationProviderCallback() { @Override public void onSuccess(double latitude, double longitude, double accuracy) { - position.set(Position.KEY_APPROXIMATE, true); - position.setValid(true); - position.setFixTime(position.getDeviceTime()); - position.setLatitude(latitude); - position.setLongitude(longitude); - position.setAccuracy(accuracy); - position.setAltitude(0); - position.setSpeed(0); - position.setCourse(0); + updatePosition(position, latitude, longitude, accuracy); ctx.fireChannelRead(position); } @@ -82,4 +91,16 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter { } } + private void updatePosition(Position position, double latitude, double longitude, double accuracy) { + position.set(Position.KEY_APPROXIMATE, true); + position.setValid(true); + position.setFixTime(position.getDeviceTime()); + position.setLatitude(latitude); + position.setLongitude(longitude); + position.setAccuracy(accuracy); + position.setAltitude(0); + position.setSpeed(0); + position.setCourse(0); + } + } diff --git a/src/main/java/org/traccar/model/CellTower.java b/src/main/java/org/traccar/model/CellTower.java index 16a28ea79..bebbb2432 100644 --- a/src/main/java/org/traccar/model/CellTower.java +++ b/src/main/java/org/traccar/model/CellTower.java @@ -19,6 +19,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import org.traccar.config.Config; import org.traccar.config.Keys; +import java.util.Objects; + @JsonInclude(JsonInclude.Include.NON_NULL) public class CellTower { @@ -111,4 +113,22 @@ public class CellTower { mobileNetworkCode = Integer.parseInt(operatorString.substring(3)); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CellTower cellTower = (CellTower) o; + return Objects.equals(radioType, cellTower.radioType) + && Objects.equals(cellId, cellTower.cellId) + && Objects.equals(locationAreaCode, cellTower.locationAreaCode) + && Objects.equals(mobileCountryCode, cellTower.mobileCountryCode) + && Objects.equals(mobileNetworkCode, cellTower.mobileNetworkCode) + && Objects.equals(signalStrength, cellTower.signalStrength); + } + + @Override + public int hashCode() { + return Objects.hash(radioType, cellId, locationAreaCode, mobileCountryCode, mobileNetworkCode, signalStrength); + } + } diff --git a/src/main/java/org/traccar/model/Network.java b/src/main/java/org/traccar/model/Network.java index 4d67fc5d8..e565f4f59 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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 @@ import com.fasterxml.jackson.annotation.JsonInclude; import java.util.ArrayList; import java.util.Collection; +import java.util.Objects; @JsonInclude(JsonInclude.Include.NON_NULL) public class Network { @@ -118,4 +119,23 @@ public class Network { wifiAccessPoints.add(wifiAccessPoint); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Network network = (Network) o; + return Objects.equals(homeMobileCountryCode, network.homeMobileCountryCode) + && Objects.equals(homeMobileNetworkCode, network.homeMobileNetworkCode) + && Objects.equals(radioType, network.radioType) + && Objects.equals(carrier, network.carrier) + && Objects.equals(cellTowers, network.cellTowers) + && Objects.equals(wifiAccessPoints, network.wifiAccessPoints); + } + + @Override + public int hashCode() { + return Objects.hash( + homeMobileCountryCode, homeMobileNetworkCode, radioType, carrier, cellTowers, wifiAccessPoints); + } + } diff --git a/src/main/java/org/traccar/model/WifiAccessPoint.java b/src/main/java/org/traccar/model/WifiAccessPoint.java index 87a77f3c0..fa7be8700 100644 --- a/src/main/java/org/traccar/model/WifiAccessPoint.java +++ b/src/main/java/org/traccar/model/WifiAccessPoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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,8 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.Objects; + @JsonInclude(JsonInclude.Include.NON_NULL) public class WifiAccessPoint { @@ -63,4 +65,19 @@ public class WifiAccessPoint { this.channel = channel; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + WifiAccessPoint that = (WifiAccessPoint) o; + return Objects.equals(macAddress, that.macAddress) + && Objects.equals(signalStrength, that.signalStrength) + && Objects.equals(channel, that.channel); + } + + @Override + public int hashCode() { + return Objects.hash(macAddress, signalStrength, channel); + } + } -- cgit v1.2.3 From 900601111466aa861db8ae77b71b95aec6c8c82e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 17:04:39 -0700 Subject: Fix code style issues --- src/main/java/org/traccar/model/CellTower.java | 8 ++++++-- src/main/java/org/traccar/model/Network.java | 8 ++++++-- src/main/java/org/traccar/model/WifiAccessPoint.java | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/model/CellTower.java b/src/main/java/org/traccar/model/CellTower.java index bebbb2432..355594c64 100644 --- a/src/main/java/org/traccar/model/CellTower.java +++ b/src/main/java/org/traccar/model/CellTower.java @@ -115,8 +115,12 @@ public class CellTower { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } CellTower cellTower = (CellTower) o; return Objects.equals(radioType, cellTower.radioType) && Objects.equals(cellId, cellTower.cellId) diff --git a/src/main/java/org/traccar/model/Network.java b/src/main/java/org/traccar/model/Network.java index e565f4f59..b31c53c38 100644 --- a/src/main/java/org/traccar/model/Network.java +++ b/src/main/java/org/traccar/model/Network.java @@ -121,8 +121,12 @@ public class Network { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } Network network = (Network) o; return Objects.equals(homeMobileCountryCode, network.homeMobileCountryCode) && Objects.equals(homeMobileNetworkCode, network.homeMobileNetworkCode) diff --git a/src/main/java/org/traccar/model/WifiAccessPoint.java b/src/main/java/org/traccar/model/WifiAccessPoint.java index fa7be8700..e28c1b935 100644 --- a/src/main/java/org/traccar/model/WifiAccessPoint.java +++ b/src/main/java/org/traccar/model/WifiAccessPoint.java @@ -67,8 +67,12 @@ public class WifiAccessPoint { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } WifiAccessPoint that = (WifiAccessPoint) o; return Objects.equals(macAddress, that.macAddress) && Objects.equals(signalStrength, that.signalStrength) -- cgit v1.2.3 From 204e98895b3cd9a37ceea1760917c07606b36b10 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 18:42:28 -0700 Subject: Migrate SMTP settings --- src/main/java/org/traccar/config/Config.java | 31 ++---- src/main/java/org/traccar/config/Keys.java | 96 ++++++++++++++++++ .../java/org/traccar/database/MailManager.java | 110 ++++++++++----------- .../traccar/notification/PropertiesProvider.java | 27 ++--- 4 files changed, 165 insertions(+), 99 deletions(-) diff --git a/src/main/java/org/traccar/config/Config.java b/src/main/java/org/traccar/config/Config.java index 5f95c16d9..c73be6475 100644 --- a/src/main/java/org/traccar/config/Config.java +++ b/src/main/java/org/traccar/config/Config.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,6 +25,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.InvalidPropertiesFormatException; +import java.util.Objects; import java.util.Properties; @Singleton @@ -71,8 +72,7 @@ public class Config { return hasKey(key.getKey()); } - @Deprecated - public boolean hasKey(String key) { + private boolean hasKey(String key) { return useEnvironmentVariables && System.getenv().containsKey(getEnvironmentVariableName(key)) || properties.containsKey(key); } @@ -102,12 +102,7 @@ public class Config { } public boolean getBoolean(ConfigKey key) { - return getBoolean(key.getKey()); - } - - @Deprecated - public boolean getBoolean(String key) { - return Boolean.parseBoolean(getString(key)); + return Boolean.parseBoolean(getString(key.getKey())); } public int getInteger(ConfigKey key) { @@ -116,11 +111,7 @@ public class Config { return Integer.parseInt(value); } else { Integer defaultValue = key.getDefaultValue(); - if (defaultValue != null) { - return defaultValue; - } else { - return 0; - } + return Objects.requireNonNullElse(defaultValue, 0); } } @@ -139,11 +130,7 @@ public class Config { return Long.parseLong(value); } else { Long defaultValue = key.getDefaultValue(); - if (defaultValue != null) { - return defaultValue; - } else { - return 0; - } + return Objects.requireNonNullElse(defaultValue, 0L); } } @@ -153,11 +140,7 @@ public class Config { return Double.parseDouble(value); } else { Double defaultValue = key.getDefaultValue(); - if (defaultValue != null) { - return defaultValue; - } else { - return 0; - } + return Objects.requireNonNullElse(defaultValue, 0.0); } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 2e1a14eaf..7ab45312f 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -800,6 +800,102 @@ public final class Keys { List.of(KeyType.CONFIG), "templates"); + /** + * Force SMTP settings from the config file and ignore user attributes. + */ + public static final ConfigKey MAIL_SMTP_IGNORE_USER_CONFIG = new BooleanConfigKey( + "mail.smtp.ignoreUserConfig", + List.of(KeyType.CONFIG)); + + /** + * The SMTP server to connect to. + */ + public static final ConfigKey MAIL_SMTP_HOST = new StringConfigKey( + "mail.smtp.host", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * The SMTP server port to connect. Defaults to 25. + */ + public static final ConfigKey MAIL_SMTP_PORT = new IntegerConfigKey( + "mail.smtp.port", + List.of(KeyType.CONFIG, KeyType.USER), + 25); + + /** + * Email transport protocol. Default value is "smtp". + */ + public static final ConfigKey MAIL_TRANSPORT_PROTOCOL = new StringConfigKey( + "mail.transport.protocol", + List.of(KeyType.CONFIG, KeyType.USER), + "smtp"); + + /** + * If true, enables the use of the STARTTLS command (if supported by the server) to switch the connection to a + * TLS-protected connection before issuing any login commands. + */ + public static final ConfigKey MAIL_SMTP_STARTTLS_ENABLE = new BooleanConfigKey( + "mail.smtp.starttls.enable", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * If true, requires the use of the STARTTLS command. If the server doesn't support the STARTTLS command, or the + * command fails, the connect method will fail. + */ + public static final ConfigKey MAIL_SMTP_STARTTLS_REQUIRED = new BooleanConfigKey( + "mail.smtp.starttls.required", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * If set to true, use SSL to connect and use the SSL port by default. + */ + public static final ConfigKey MAIL_SMTP_SSL_ENABLE = new BooleanConfigKey( + "mail.smtp.ssl.enable", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * If set to "*", all hosts are trusted. If set to a whitespace separated list of hosts, those hosts are trusted. + * Otherwise, trust depends on the certificate the server presents. + */ + public static final ConfigKey MAIL_SMTP_SSL_TRUST = new StringConfigKey( + "mail.smtp.ssl.trust", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * Specifies the SSL protocols that will be enabled for SSL connections. + */ + public static final ConfigKey MAIL_SMTP_SSL_PROTOCOLS = new StringConfigKey( + "mail.smtp.ssl.protocols", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * SMTP connection username. + */ + public static final ConfigKey MAIL_SMTP_USERNAME = new StringConfigKey( + "mail.smtp.username", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * SMTP connection password. + */ + public static final ConfigKey MAIL_SMTP_PASSWORD = new StringConfigKey( + "mail.smtp.password", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * Email address to use for SMTP MAIL command. + */ + public static final ConfigKey MAIL_SMTP_FROM = new StringConfigKey( + "mail.smtp.from", + List.of(KeyType.CONFIG, KeyType.USER)); + + /** + * The personal name for the email from address. + */ + public static final ConfigKey MAIL_SMTP_FROM_NAME = new StringConfigKey( + "mail.smtp.fromName", + List.of(KeyType.CONFIG, KeyType.USER)); + /** * SMS API service full URL. Enables SMS commands and notifications. */ diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java index 72b8b72c1..ec1681dcb 100644 --- a/src/main/java/org/traccar/database/MailManager.java +++ b/src/main/java/org/traccar/database/MailManager.java @@ -17,6 +17,8 @@ package org.traccar.database; import org.traccar.config.Config; +import org.traccar.config.ConfigKey; +import org.traccar.config.Keys; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; @@ -37,6 +39,8 @@ import java.util.Properties; public final class MailManager { + private static final String CONTENT_TYPE = "text/html; charset=utf-8"; + private final Config config; private final StatisticsManager statisticsManager; @@ -46,59 +50,48 @@ public final class MailManager { this.statisticsManager = statisticsManager; } - private static Properties getProperties(PropertiesProvider provider) { - Properties properties = new Properties(); - String host = provider.getString("mail.smtp.host"); - if (host != null) { - properties.put("mail.transport.protocol", provider.getString("mail.transport.protocol", "smtp")); - properties.put("mail.smtp.host", host); - properties.put("mail.smtp.port", String.valueOf(provider.getInteger("mail.smtp.port", 25))); - - Boolean starttlsEnable = provider.getBoolean("mail.smtp.starttls.enable"); - if (starttlsEnable != null) { - properties.put("mail.smtp.starttls.enable", String.valueOf(starttlsEnable)); - } - Boolean starttlsRequired = provider.getBoolean("mail.smtp.starttls.required"); - if (starttlsRequired != null) { - properties.put("mail.smtp.starttls.required", String.valueOf(starttlsRequired)); - } - - Boolean sslEnable = provider.getBoolean("mail.smtp.ssl.enable"); - if (sslEnable != null) { - properties.put("mail.smtp.ssl.enable", String.valueOf(sslEnable)); - } - String sslTrust = provider.getString("mail.smtp.ssl.trust"); - if (sslTrust != null) { - properties.put("mail.smtp.ssl.trust", sslTrust); - } + private static void copyBooleanProperty( + Properties properties, PropertiesProvider provider, ConfigKey key) { + Boolean value = provider.getBoolean(key); + if (value != null) { + properties.put(key.getKey(), String.valueOf(value)); + } + } - String sslProtocols = provider.getString("mail.smtp.ssl.protocols"); - if (sslProtocols != null) { - properties.put("mail.smtp.ssl.protocols", sslProtocols); - } + private static void copyStringProperty( + Properties properties, PropertiesProvider provider, ConfigKey key) { + String value = provider.getString(key); + if (value != null) { + properties.put(key.getKey(), value); + } + } - String username = provider.getString("mail.smtp.username"); - if (username != null) { - properties.put("mail.smtp.username", username); - } - String password = provider.getString("mail.smtp.password"); - if (password != null) { - properties.put("mail.smtp.password", password); - } - String from = provider.getString("mail.smtp.from"); - if (from != null) { - properties.put("mail.smtp.from", from); - } - String fromName = provider.getString("mail.smtp.fromName"); - if (fromName != null) { - properties.put("mail.smtp.fromName", fromName); - } + private static Properties getProperties(PropertiesProvider provider) { + String host = provider.getString(Keys.MAIL_SMTP_HOST); + if (host != null) { + Properties properties = new Properties(); + + properties.put(Keys.MAIL_TRANSPORT_PROTOCOL.getKey(), provider.getString(Keys.MAIL_TRANSPORT_PROTOCOL)); + properties.put(Keys.MAIL_SMTP_HOST.getKey(), host); + properties.put(Keys.MAIL_SMTP_PORT.getKey(), String.valueOf(provider.getInteger(Keys.MAIL_SMTP_PORT))); + + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_ENABLE); + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_REQUIRED); + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_SSL_ENABLE); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_TRUST); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_PROTOCOLS); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_USERNAME); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_PASSWORD); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM_NAME); + + return properties; } - return properties; + return null; } public boolean getEmailEnabled() { - return config.hasKey("mail.smtp.host"); + return config.hasKey(Keys.MAIL_SMTP_HOST); } public void sendMessage( @@ -108,24 +101,25 @@ public final class MailManager { public void sendMessage( User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { + Properties properties = null; - if (!config.getBoolean("mail.smtp.ignoreUserConfig")) { + if (!config.getBoolean(Keys.MAIL_SMTP_IGNORE_USER_CONFIG)) { properties = getProperties(new PropertiesProvider(user)); } - if (properties == null || !properties.containsKey("mail.smtp.host")) { + if (properties == null) { properties = getProperties(new PropertiesProvider(config)); } - if (!properties.containsKey("mail.smtp.host")) { - throw new RuntimeException("No SMTP configuration found"); + if (properties == null) { + throw new MessagingException("No SMTP configuration found"); } Session session = Session.getInstance(properties); MimeMessage message = new MimeMessage(session); - String from = properties.getProperty("mail.smtp.from"); + String from = properties.getProperty(Keys.MAIL_SMTP_FROM.getKey()); if (from != null) { - String fromName = properties.getProperty("mail.smtp.fromName"); + String fromName = properties.getProperty(Keys.MAIL_SMTP_FROM_NAME.getKey()); if (fromName != null) { try { message.setFrom(new InternetAddress(from, fromName)); @@ -145,21 +139,21 @@ public final class MailManager { Multipart multipart = new MimeMultipart(); BodyPart messageBodyPart = new MimeBodyPart(); - messageBodyPart.setContent(body, "text/html; charset=utf-8"); + messageBodyPart.setContent(body, CONTENT_TYPE); multipart.addBodyPart(messageBodyPart); multipart.addBodyPart(attachment); message.setContent(multipart); } else { - message.setContent(body, "text/html; charset=utf-8"); + message.setContent(body, CONTENT_TYPE); } try (Transport transport = session.getTransport()) { statisticsManager.registerMail(); transport.connect( - properties.getProperty("mail.smtp.host"), - properties.getProperty("mail.smtp.username"), - properties.getProperty("mail.smtp.password")); + properties.getProperty(Keys.MAIL_SMTP_HOST.getKey()), + properties.getProperty(Keys.MAIL_SMTP_USERNAME.getKey()), + properties.getProperty(Keys.MAIL_SMTP_PASSWORD.getKey())); transport.sendMessage(message, message.getAllRecipients()); } } diff --git a/src/main/java/org/traccar/notification/PropertiesProvider.java b/src/main/java/org/traccar/notification/PropertiesProvider.java index f0078feef..4ffad432c 100644 --- a/src/main/java/org/traccar/notification/PropertiesProvider.java +++ b/src/main/java/org/traccar/notification/PropertiesProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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.notification; import org.traccar.config.Config; +import org.traccar.config.ConfigKey; import org.traccar.model.ExtendedModel; public class PropertiesProvider { @@ -32,36 +33,28 @@ public class PropertiesProvider { this.extendedModel = extendedModel; } - public String getString(String key) { + public String getString(ConfigKey key) { if (config != null) { return config.getString(key); } else { - return extendedModel.getString(key); + return extendedModel.getString(key.getKey()); } } - public String getString(String key, String defaultValue) { - String value = getString(key); - if (value == null) { - value = defaultValue; - } - return value; - } - - public int getInteger(String key, int defaultValue) { + public int getInteger(ConfigKey key) { if (config != null) { - return config.getInteger(key, defaultValue); + return config.getInteger(key); } else { - Object result = extendedModel.getAttributes().get(key); + Object result = extendedModel.getAttributes().get(key.getKey()); if (result != null) { return result instanceof String ? Integer.parseInt((String) result) : (Integer) result; } else { - return defaultValue; + return key.getDefaultValue(); } } } - public Boolean getBoolean(String key) { + public Boolean getBoolean(ConfigKey key) { if (config != null) { if (config.hasKey(key)) { return config.getBoolean(key); @@ -69,7 +62,7 @@ public class PropertiesProvider { return null; } } else { - Object result = extendedModel.getAttributes().get(key); + Object result = extendedModel.getAttributes().get(key.getKey()); if (result != null) { return result instanceof String ? Boolean.valueOf((String) result) : (Boolean) result; } else { -- cgit v1.2.3 From 27e8b2f8b24b12ddc4662c5559419d72755bbf08 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 14 Jul 2022 18:50:44 -0700 Subject: Filter for old data (fix #3800) --- src/main/java/org/traccar/config/Keys.java | 12 ++++++++++-- src/main/java/org/traccar/handler/FilterHandler.java | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 7ab45312f..5f31fe99c 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1104,13 +1104,21 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * Filter records with fix time in future. The values is specified in seconds. Records that have fix time more than - * specified number of seconds later than current server time would be filtered out. + * Filter records with fix time in the future. The value is specified in seconds. Records that have fix time more + * than the specified number of seconds later than current server time would be filtered out. */ public static final ConfigKey FILTER_FUTURE = new LongConfigKey( "filter.future", List.of(KeyType.CONFIG)); + /** + * Filter records with fix time in the past. The value is specified in seconds. Records that have fix time more + * than the specified number of seconds before current server time would be filtered out. + */ + public static final ConfigKey FILTER_PAST = new LongConfigKey( + "filter.past", + List.of(KeyType.CONFIG)); + /** * Filter positions with accuracy less than specified value in meters. */ diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 0bd57319a..37f5cd566 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -47,6 +47,7 @@ public class FilterHandler extends BaseDataHandler { private final boolean filterZero; private final boolean filterDuplicate; private final long filterFuture; + private final long filterPast; private final boolean filterApproximate; private final int filterAccuracy; private final boolean filterStatic; @@ -67,6 +68,7 @@ public class FilterHandler extends BaseDataHandler { filterZero = config.getBoolean(Keys.FILTER_ZERO); filterDuplicate = config.getBoolean(Keys.FILTER_DUPLICATE); filterFuture = config.getLong(Keys.FILTER_FUTURE) * 1000; + filterPast = config.getLong(Keys.FILTER_PAST) * 1000; filterAccuracy = config.getInteger(Keys.FILTER_ACCURACY); filterApproximate = config.getBoolean(Keys.FILTER_APPROXIMATE); filterStatic = config.getBoolean(Keys.FILTER_STATIC); @@ -116,6 +118,10 @@ public class FilterHandler extends BaseDataHandler { return filterFuture != 0 && position.getFixTime().getTime() > System.currentTimeMillis() + filterFuture; } + private boolean filterPast(Position position) { + return filterPast != 0 && position.getFixTime().getTime() < System.currentTimeMillis() - filterPast; + } + private boolean filterAccuracy(Position position) { return filterAccuracy != 0 && position.getAccuracy() > filterAccuracy; } @@ -185,6 +191,9 @@ public class FilterHandler extends BaseDataHandler { if (filterFuture(position)) { filterType.append("Future "); } + if (filterPast(position)) { + filterType.append("Past "); + } if (filterAccuracy(position)) { filterType.append("Accuracy "); } -- cgit v1.2.3 From 6a39fec53770002149d70ba3b09b8bf1f03a5780 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 07:12:47 -0700 Subject: Remove misused timezone --- src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java b/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java index 92dae7285..b07b94e20 100644 --- a/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AustinNbProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; import java.net.SocketAddress; -import java.util.TimeZone; import java.util.regex.Pattern; public class AustinNbProtocolDecoder extends BaseProtocolDecoder { @@ -64,7 +63,7 @@ public class AustinNbProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS, TimeZone.getDefault().getID())); + position.setTime(parser.nextDateTime()); position.setValid(true); position.setLatitude(Double.parseDouble(parser.next().replace(',', '.'))); -- cgit v1.2.3 From 80bbf6e1b1903ba9218245c4fe94e5b482b59dad Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 07:13:21 -0700 Subject: Support ITS custom timezone (fix #4232) --- src/main/java/org/traccar/protocol/ItsProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java index 1ed9a7d8c..8a8d734cf 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java @@ -205,7 +205,8 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { position.setValid(parser.nextInt() == 1); } - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setTime(parser.nextDateTime( + Parser.DateTimeFormat.DMY_HMS, getTimeZone(deviceSession.getDeviceId()).getID())); if (parser.hasNext()) { position.setValid(parser.next().matches("[1A]")); } -- cgit v1.2.3 From 16e63283a2b64b2e1b490701c219beed653f2b17 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 07:29:55 -0700 Subject: Fix password update --- src/main/java/org/traccar/api/BaseObjectResource.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 2a3bbe239..408594315 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -98,6 +98,10 @@ public abstract class BaseObjectResource extends BaseResour storage.updateObject(entity, new Request( new Columns.Exclude("id"), new Condition.Equals("id", "id"))); + if (entity instanceof User) { + storage.updateObject(entity, new Request( + new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + } cacheManager.updateOrInvalidate(true, entity); LogAction.edit(getUserId(), entity); -- cgit v1.2.3 From 159f0ef4861b64085cdd1c1d8d0234f47bc75797 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 08:03:57 -0700 Subject: Update only if password changed --- src/main/java/org/traccar/api/BaseObjectResource.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 408594315..0ec2bfeaa 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -99,8 +99,11 @@ public abstract class BaseObjectResource extends BaseResour new Columns.Exclude("id"), new Condition.Equals("id", "id"))); if (entity instanceof User) { - storage.updateObject(entity, new Request( - new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + User user = (User) entity; + if (user.getHashedPassword() != null) { + storage.updateObject(entity, new Request( + new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + } } cacheManager.updateOrInvalidate(true, entity); LogAction.edit(getUserId(), entity); -- cgit v1.2.3 From ca4488bd093d25afa494ab30e117fdef98e20013 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 11:41:53 -0700 Subject: Migrate to Firebase SDK --- build.gradle | 1 + src/main/java/org/traccar/config/Keys.java | 6 +- .../traccar/notificators/NotificatorFirebase.java | 86 +++++++++++----------- .../traccar/notificators/NotificatorTraccar.java | 55 +++++++++++++- 4 files changed, 100 insertions(+), 48 deletions(-) diff --git a/build.gradle b/build.gradle index 8ba907843..675d1490f 100644 --- a/build.gradle +++ b/build.gradle @@ -83,6 +83,7 @@ dependencies { implementation "com.sun.xml.bind:jaxb-impl:3.0.2" implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.141" + implementation "com.google.firebase:firebase-admin:9.0.0" testImplementation "junit:junit:4.13.2" testImplementation "org.mockito:mockito-core:3.+" } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 5f31fe99c..1217ab94c 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -978,10 +978,10 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * Firebase server API key for push notifications. + * Firebase service account JSON. */ - public static final ConfigKey NOTIFICATOR_FIREBASE_KEY = new StringConfigKey( - "notificator.firebase.key", + public static final ConfigKey NOTIFICATOR_FIREBASE_SERVICE_ACCOUNT = new StringConfigKey( + "notificator.firebase.serviceAccount", List.of(KeyType.CONFIG)); /** diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 17a6735ee..ecf3fbb70 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -16,73 +16,77 @@ */ package org.traccar.notificators; -import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.messaging.AndroidConfig; +import com.google.firebase.messaging.AndroidNotification; +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.FirebaseMessagingException; +import com.google.firebase.messaging.MulticastMessage; +import com.google.firebase.messaging.Notification; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; +import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; +import javax.inject.Singleton; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +@Singleton public class NotificatorFirebase implements Notificator { private final NotificationFormatter notificationFormatter; - private final Client client; - private final String url; - private final String key; + @Inject + public NotificatorFirebase(Config config, NotificationFormatter notificationFormatter) throws IOException { - public static class Notification { - @JsonProperty("title") - private String title; - @JsonProperty("body") - private String body; - @JsonProperty("sound") - private String sound; - } + this.notificationFormatter = notificationFormatter; - public static class Message { - @JsonProperty("registration_ids") - private String[] tokens; - @JsonProperty("notification") - private Notification notification; - } + InputStream serviceAccount = new ByteArrayInputStream( + config.getString(Keys.NOTIFICATOR_FIREBASE_SERVICE_ACCOUNT).getBytes()); - @Inject - public NotificatorFirebase(Config config, NotificationFormatter notificationFormatter, Client client) { - this( - notificationFormatter, client, "https://fcm.googleapis.com/fcm/send", - config.getString(Keys.NOTIFICATOR_FIREBASE_KEY)); - } + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(GoogleCredentials.fromStream(serviceAccount)) + .build(); - protected NotificatorFirebase( - NotificationFormatter notificationFormatter, Client client, String url, String key) { - this.notificationFormatter = notificationFormatter; - this.client = client; - this.url = url; - this.key = key; + FirebaseApp.initializeApp(options); } @Override - public void send(User user, Event event, Position position) { + public void send(User user, Event event, Position position) throws MessageException { if (user.hasAttribute("notificationTokens")) { var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); - Notification notification = new Notification(); - notification.title = shortMessage.getSubject(); - notification.body = shortMessage.getBody(); - notification.sound = "default"; + List registrationTokens = Arrays.asList(user.getString("notificationTokens").split("[, ]")); - Message message = new Message(); - message.tokens = user.getString("notificationTokens").split("[, ]"); - message.notification = notification; + MulticastMessage message = MulticastMessage.builder() + .setNotification(Notification.builder() + .setTitle(shortMessage.getSubject()) + .setBody(shortMessage.getBody()) + .build()) + .setAndroidConfig(AndroidConfig.builder() + .setNotification(AndroidNotification.builder() + .setSound("default") + .build()) + .build()) + .addAllTokens(registrationTokens) + .build(); - client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); + try { + FirebaseMessaging.getInstance().sendMulticast(message); + } catch (FirebaseMessagingException e) { + throw new MessageException(e); + } } } diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 8f1260e96..cb8647335 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -15,20 +15,67 @@ */ package org.traccar.notificators; +import com.fasterxml.jackson.annotation.JsonProperty; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; -public class NotificatorTraccar extends NotificatorFirebase { +public class NotificatorTraccar implements Notificator { + + private final NotificationFormatter notificationFormatter; + private final Client client; + + private final String url; + private final String key; + + public static class Notification { + @JsonProperty("title") + private String title; + @JsonProperty("body") + private String body; + @JsonProperty("sound") + private String sound; + } + + public static class Message { + @JsonProperty("registration_ids") + private String[] tokens; + @JsonProperty("notification") + private Notification notification; + } @Inject public NotificatorTraccar(Config config, NotificationFormatter notificationFormatter, Client client) { - super( - notificationFormatter, client, "https://www.traccar.org/push/", - config.getString(Keys.NOTIFICATOR_TRACCAR_KEY)); + this.notificationFormatter = notificationFormatter; + this.client = client; + this.url = "http://localhost:3001/push/"; + this.key = config.getString(Keys.NOTIFICATOR_TRACCAR_KEY); + } + + @Override + public void send(User user, Event event, Position position) { + if (user.hasAttribute("notificationTokens")) { + + var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); + + Notification notification = new Notification(); + notification.title = shortMessage.getSubject(); + notification.body = shortMessage.getBody(); + notification.sound = "default"; + + Message message = new Message(); + message.tokens = user.getString("notificationTokens").split("[, ]"); + message.notification = notification; + + client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); + } } } -- cgit v1.2.3 From ee30e6e63f110476f557ed4ca8a081eb5b589101 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 16 Jul 2022 20:47:59 -0700 Subject: Parameter to enable protocols (fix #3991) --- src/main/java/org/traccar/ServerManager.java | 18 ++++++++++++++---- src/main/java/org/traccar/config/Keys.java | 10 ++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/ServerManager.java b/src/main/java/org/traccar/ServerManager.java index 8d6e615dc..57afb01fd 100644 --- a/src/main/java/org/traccar/ServerManager.java +++ b/src/main/java/org/traccar/ServerManager.java @@ -28,9 +28,12 @@ import java.io.IOException; import java.net.BindException; import java.net.ConnectException; import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @Singleton @@ -44,11 +47,18 @@ public class ServerManager implements LifecycleObject { @Inject public ServerManager( Injector injector, Config config) throws IOException, URISyntaxException, ReflectiveOperationException { + Set enabledProtocols = null; + if (config.hasKey(Keys.PROTOCOLS_ENABLE)) { + enabledProtocols = new HashSet<>(Arrays.asList(config.getString(Keys.PROTOCOLS_ENABLE).split("[, ]"))); + } for (Class protocolClass : ClassScanner.findSubclasses(BaseProtocol.class, "org.traccar.protocol")) { - if (config.hasKey(Keys.PROTOCOL_PORT.withPrefix(BaseProtocol.nameFromClass(protocolClass)))) { - BaseProtocol protocol = (BaseProtocol) injector.getInstance(protocolClass); - connectorList.addAll(protocol.getConnectorList()); - protocolList.put(protocol.getName(), protocol); + String protocolName = BaseProtocol.nameFromClass(protocolClass); + if (enabledProtocols == null || enabledProtocols.contains(protocolName)) { + if (config.hasKey(Keys.PROTOCOL_PORT.withPrefix(protocolName))) { + BaseProtocol protocol = (BaseProtocol) injector.getInstance(protocolClass); + connectorList.addAll(protocol.getConnectorList()); + protocolList.put(protocol.getName(), protocol); + } } } } diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 1217ab94c..2190f82f7 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1210,6 +1210,16 @@ public final class Keys { "time.override", List.of(KeyType.CONFIG)); + /** + * List of protocols to enable. If not specified, Traccar enabled all protocols that have port numbers listed. + * The value is a comma-separated list of protocol names. + * + * Example value: teltonika,osmand + */ + public static final ConfigKey PROTOCOLS_ENABLE = new StringConfigKey( + "protocols.enable", + List.of(KeyType.CONFIG)); + /** * List of protocols for overriding time. If not specified override is applied globally. List consist of protocol * names that can be separated by comma or single space character. -- cgit v1.2.3 From 09a85fa9e43b9781d3d8e12bbbe0ff42a7d02b12 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Jul 2022 08:11:29 -0700 Subject: Support C2Stek variation (fix #4331) --- .../java/org/traccar/protocol/C2stekProtocolDecoder.java | 12 ++++++++---- .../java/org/traccar/protocol/C2stekProtocolDecoderTest.java | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java index 42a61ef85..aef158fc7 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java @@ -49,10 +49,12 @@ public class C2stekProtocolDecoder extends BaseProtocolDecoder { .number("(-?d+.d+)#") // altitude .number("(d+)#") // battery .number("d+#") // geo area alarm - .number("(x+)#") // alarm - .number("([01])?") // armed + .number("(x+)") // alarm + .groupBegin() + .number("#([01])?") // armed .number("([01])") // door .number("([01])#") // ignition + .groupEnd("?") .any() .text("$AP") .compile(); @@ -114,8 +116,10 @@ public class C2stekProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { position.set(Position.KEY_ARMED, parser.nextInt() > 0); } - position.set(Position.KEY_DOOR, parser.nextInt() > 0); - position.set(Position.KEY_IGNITION, parser.nextInt() > 0); + if (parser.hasNext(2)) { + position.set(Position.KEY_DOOR, parser.nextInt() > 0); + position.set(Position.KEY_IGNITION, parser.nextInt() > 0); + } return position; } diff --git a/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java index fbb530e7f..28876075d 100644 --- a/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/C2stekProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class C2stekProtocolDecoderTest extends ProtocolTest { var decoder = inject(new C2stekProtocolDecoder(null)); + verifyPosition(decoder, text( + "PA$012207006145046$D#190607#123157#1#37.947087#023.768669#000.00#314.6#00000.0#4104#000#8$AP")); + verifyPosition(decoder, text( "PA$867965024889327$D#220222#135059#0#+37.98995#+23.85141#0.00#69.2#0.0#0000#000#8#00#sz-w1001#B2600$AP")); -- cgit v1.2.3 From a9f0507d6c08aa00afb41d9e3222cdfdafd54740 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Jul 2022 09:09:50 -0700 Subject: More integration tests --- tools/test-integration.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tools/test-integration.py b/tools/test-integration.py index 42922147e..4a590128f 100755 --- a/tools/test-integration.py +++ b/tools/test-integration.py @@ -89,7 +89,7 @@ messages = { 'siwi' : '$SIWI,1234,1320,A,0,,1,1,0,0,876578,43,10,A,19.0123456,72.65347,45,0,055929,071107,22,5,1,0,3700,1210,0,2500,1230,321,0,1.1,4.0,1!\r\n', 'starlink' : '$SLU123456,06,622,170329035057,01,170329035057,+3158.0018,+03446.6968,004.9,007,000099,1,1,0,0,0,0,0,0,,,14.176,03.826,,1,1,1,4*B0\r\n', 'alematics' : '$T,50,592,123456789012345,20170515062915,20170515062915,25.035005,121.561555,0,31,89,3.7,5,1,0,0.000,12.752,1629,38,12752,4203,6\r\n', - 'vtfms' : '(123456789012345,00I76,00,000,,,,,A,133755,210617,10.57354,077.24912,SW,000,00598,00000,K,0017368,1,12.7,,,0.000,,,0,0,0,0,1,1,0,,)074' + 'vtfms' : '(123456789012345,00I76,00,000,,,,,A,133755,210617,10.57354,077.24912,SW,000,00598,00000,K,0017368,1,12.7,,,0.000,,,0,0,0,0,1,1,0,,)074', 'esky': 'ET;0;123456789012345;R;6+190317162511+41.32536+19.83144+0.14+0+0x0+0+18460312+0+1233+192', 'genx': '123456789012345,08/31/2017 17:24:13,45.47275,-73.65491,5,19,117,1.14,147,ON,1462,0,6,N,0,0.000,-95.0,-1.0,0,0.0000,0.0000,0.000,0,0.00,0.00,0.00,NA,U,UUU,0,-95.0,U\r\n', 'dway': 'AA55,115,1234,1,171024,195059,28.0153,-82.4761,3, 1.0,319,1000,0000,00000,4244,0,0,0,D\r\n', @@ -99,6 +99,16 @@ messages = { 'm2c': '[#M2C,2020,P1.B1.H1.F1.R1,101,123456789012345,2,L,1,100,170704,074933,28.647556,77.192940,900,194,0.0,0,0,0,255,11942,0,0,0,0,0,0,0,0,30068,5051,0,0,1*8159\r\n]', 'cautela': '20,123456789012,14,02,18,16.816667,96.166667,1325,S,*2E\r\n', 'pt60': '@B#@|01|001|123456789012345|9425010450971470|1|45|20181127122717|32.701093|35.570938|1|@R#@', + 'telemax': '%061234560128\r\nY000007C6999999067374074649003C00A7018074666F60D66818051304321900000000C5\r\n', + 'svias': '[7061,3041,57,1234567890,710,40618,141342,-93155840,-371754060,0,20469,0,16,1,0,0,11323,100,9,,32,4695]', + 'eseal': '##S,eSeal,123456,256,3.0.6,Normal,34,2017-08-31,08:14:40,15,A,25.708828N 100.372870W,10,0,Close,0.71,0:0:3:0,3.8,-73,E##\r\n', + 'avema': '1234567890,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\r\n', + 'milesmate': 'ApiString={A:123456789012345,B:09.8,C:00.0,D:083506,E:2838.5529N,F:07717.8049E,G:000.00,H:170918,I:G,J:00004100,K:0000000A,L:1234,M:126.86}\r\n', + 'smartsole': '#GTXRP=123456789012345,8,180514200051,34.041981,-118.255806,60,1,1,7,1.80,180514200051,4.16,11$', + 'its': '$,EPB,SEM,123456789012345,NM,14072020112020,A,28.359959,N,076.927566,E,260.93,0.1,0.0,G,NA00000000,N.A0000000,*', + 'xrb28': '*SCOR,OM,123456789012345,D0,0,012102.00,A,0608.00062,S,10659.70331,E,12,0.69,151118,30.3,M,A#\r\n', + 'c2stek': 'PA$123456789012345$D#220222#135059#0#+37.98995#+23.85141#0.00#69.2#0.0#0000#000#8#00#sz-w1001#B2600$AP', + 'mictrack': 'MT;6;123456789012345;R0;10+190109091803+22.63827+114.02922+2.14+69+2+3744+113', } baseUrl = 'http://localhost:8082' -- cgit v1.2.3 From e475512473459b596e432dc2743784b6d58243ea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Jul 2022 09:35:19 -0700 Subject: Update version numbers --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 675d1490f..36fc2f6df 100644 --- a/build.gradle +++ b/build.gradle @@ -98,7 +98,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.1", + "Implementation-Version": "5.2", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 32d1846f5..7734f3956 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.1 +AppVersion=5.2 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index ecdc4a407..77ca20ce2 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.1", + "version": "5.2", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From f12927f06fad1240f368773940719a7f93ae02d5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Jul 2022 10:46:16 -0700 Subject: Update submodule commit --- traccar-web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traccar-web b/traccar-web index 97ee71bbf..33f9da8e9 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit 97ee71bbfc9edd8ac15da97c0c4eb4f2b8aa8080 +Subproject commit 33f9da8e98763416d7f440e7ac4b8177c929eaff -- cgit v1.2.3 From 6713984001dbdd838d6d8dabcfd252e768f018c4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Jul 2022 18:45:33 -0700 Subject: Fix group caching --- src/main/java/org/traccar/session/cache/CacheManager.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 58eb95327..0865b2647 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -23,6 +23,7 @@ import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; +import org.traccar.model.Group; import org.traccar.model.GroupedModel; import org.traccar.model.Maintenance; import org.traccar.model.Notification; @@ -52,6 +53,7 @@ import java.util.stream.Collectors; @Singleton public class CacheManager implements BroadcastInterface { + private static final int GROUP_DEPTH_LIMIT = 3; private static final Collection> CLASSES = Arrays.asList( Attribute.class, Driver.class, Geofence.class, Maintenance.class, Notification.class); @@ -276,6 +278,17 @@ public class CacheManager implements BroadcastInterface { if (device != null) { addObject(deviceId, device); + int groupDepth = 0; + long groupId = device.getGroupId(); + while (groupDepth < GROUP_DEPTH_LIMIT && groupId > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", groupId))); + links.computeIfAbsent(Group.class, k -> new LinkedList<>()).add(group.getId()); + addObject(deviceId, group); + groupId = group.getGroupId(); + groupDepth += 1; + } + for (Class clazz : CLASSES) { var objects = storage.getObjects(clazz, new Request( new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); -- cgit v1.2.3 From cf2583cec5f6b9c92730bdcdc5805944ff0bfa59 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 09:08:01 -0700 Subject: OsmAnd missing coordinates (fix #4420) --- .../org/traccar/protocol/OsmAndProtocolDecoder.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java index 3574dd2a3..5f8e7424b 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@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,6 +59,8 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { position.setValid(true); Network network = new Network(); + Double latitude = null; + Double longitude = null; for (Map.Entry> entry : params.entrySet()) { for (String value : entry.getValue()) { @@ -92,15 +94,15 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { } break; case "lat": - position.setLatitude(Double.parseDouble(value)); + latitude = Double.parseDouble(value); break; case "lon": - position.setLongitude(Double.parseDouble(value)); + longitude = Double.parseDouble(value); break; case "location": String[] location = value.split(","); - position.setLatitude(Double.parseDouble(location[0])); - position.setLongitude(Double.parseDouble(location[1])); + latitude = Double.parseDouble(location[0]); + longitude = Double.parseDouble(location[1]); break; case "cell": String[] cell = value.split(","); @@ -170,7 +172,10 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { position.setNetwork(network); } - if (position.getLatitude() == 0 && position.getLongitude() == 0) { + if (latitude != null && longitude != null) { + position.setLatitude(latitude); + position.setLongitude(longitude); + } else { getLastLocation(position, position.getDeviceTime()); } -- cgit v1.2.3 From 8bc3c8c7d2c762ec00bfb1960dcd02171b7312a6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 16:52:31 -0700 Subject: Disable email change (fix #3878) --- schema/changelog-5.3.xml | 21 +++++++++++++++++++++ schema/changelog-master.xml | 1 + .../traccar/api/security/PermissionsService.java | 6 +++++- src/main/java/org/traccar/model/Server.java | 11 +++++++++++ src/main/java/org/traccar/model/User.java | 15 +++++++++++++-- .../java/org/traccar/model/UserRestrictions.java | 1 + 6 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 schema/changelog-5.3.xml diff --git a/schema/changelog-5.3.xml b/schema/changelog-5.3.xml new file mode 100644 index 000000000..b574a67d2 --- /dev/null +++ b/schema/changelog-5.3.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index 83a1ac865..cea15397d 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -33,5 +33,6 @@ + diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index a3e7a182f..a494c0257 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -166,13 +166,17 @@ public class PermissionsService { || before.getDeviceReadonly() != after.getDeviceReadonly() || before.getDisabled() != after.getDisabled() || before.getLimitCommands() != after.getLimitCommands() - || before.getDisableReports() != after.getDisableReports()) { + || before.getDisableReports() != after.getDisableReports() + || before.getFixedEmail() != after.getFixedEmail()) { if (userId == after.getId()) { checkAdmin(userId); } else { checkUser(userId, after.getId()); } } + if (before.getFixedEmail() && !before.getEmail().equals(after.getEmail())) { + checkAdmin(userId); + } } public void checkPermission( diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index e39da1b16..9e248e7bb 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -177,6 +177,17 @@ public class Server extends ExtendedModel implements UserRestrictions { this.disableReports = disableReports; } + private boolean fixedEmail; + + @Override + public boolean getFixedEmail() { + return fixedEmail; + } + + public void setFixedEmail(boolean fixedEmail) { + this.fixedEmail = fixedEmail; + } + private String poiLayer; public String getPoiLayer() { diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 9dd84ad14..0aa67168f 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -232,8 +232,6 @@ public class User extends ExtendedModel implements UserRestrictions { this.limitCommands = limitCommands; } - private String poiLayer; - private boolean disableReports; @Override @@ -245,6 +243,19 @@ public class User extends ExtendedModel implements UserRestrictions { this.disableReports = disableReports; } + private boolean fixedEmail; + + @Override + public boolean getFixedEmail() { + return fixedEmail; + } + + public void setFixedEmail(boolean fixedEmail) { + this.fixedEmail = fixedEmail; + } + + private String poiLayer; + public String getPoiLayer() { return poiLayer; } diff --git a/src/main/java/org/traccar/model/UserRestrictions.java b/src/main/java/org/traccar/model/UserRestrictions.java index 2e4e5e363..1fcc5682e 100644 --- a/src/main/java/org/traccar/model/UserRestrictions.java +++ b/src/main/java/org/traccar/model/UserRestrictions.java @@ -20,4 +20,5 @@ public interface UserRestrictions { boolean getDeviceReadonly(); boolean getLimitCommands(); boolean getDisableReports(); + boolean getFixedEmail(); } -- cgit v1.2.3 From eb79bc251669ed8d107aaf1e2a6beeb0743eacf7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 17:08:52 -0700 Subject: Improve event type order --- .../traccar/api/resource/NotificationResource.java | 33 +++++++++++----------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index a42de687d..2e4ad12f3 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -15,22 +15,6 @@ */ package org.traccar.api.resource; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.api.ExtendedObjectResource; @@ -42,6 +26,21 @@ import org.traccar.notification.MessageException; import org.traccar.notification.NotificatorManager; import org.traccar.storage.StorageException; +import javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + @Path("notifications") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -59,7 +58,7 @@ public class NotificationResource extends ExtendedObjectResource { @GET @Path("types") public Collection get() { - Set types = new HashSet<>(); + List types = new LinkedList<>(); Field[] fields = Event.class.getDeclaredFields(); for (Field field : fields) { if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { -- cgit v1.2.3 From 9cccb2f86c5ecf4041772d28fbc78ddbd619885f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 18:24:09 -0700 Subject: Remove trailing spaces --- templates/full/commandResult.vm | 2 +- templates/full/deviceFuelDrop.vm | 2 +- templates/full/deviceInactive.vm | 2 +- templates/full/deviceMoving.vm | 2 +- templates/full/deviceOffline.vm | 2 +- templates/full/deviceOnline.vm | 2 +- templates/full/deviceOverspeed.vm | 2 +- templates/full/deviceStopped.vm | 2 +- templates/full/deviceUnknown.vm | 2 +- templates/full/driverChanged.vm | 2 +- templates/full/geofenceEnter.vm | 2 +- templates/full/geofenceExit.vm | 2 +- templates/full/ignitionOff.vm | 2 +- templates/full/ignitionOn.vm | 2 +- templates/full/maintenance.vm | 2 +- templates/full/test.vm | 2 +- templates/full/textMessage.vm | 4 ++-- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/templates/full/commandResult.vm b/templates/full/commandResult.vm index c5ceffab0..443e1a399 100644 --- a/templates/full/commandResult.vm +++ b/templates/full/commandResult.vm @@ -7,4 +7,4 @@ Result: $position.getString("result")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Link: $webUrl?eventId=$event.id - + diff --git a/templates/full/deviceFuelDrop.vm b/templates/full/deviceFuelDrop.vm index a50e8ca38..bf7a16b97 100644 --- a/templates/full/deviceFuelDrop.vm +++ b/templates/full/deviceFuelDrop.vm @@ -6,4 +6,4 @@ Device: $device.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
- + diff --git a/templates/full/deviceInactive.vm b/templates/full/deviceInactive.vm index 51aead653..626db1dc4 100644 --- a/templates/full/deviceInactive.vm +++ b/templates/full/deviceInactive.vm @@ -9,4 +9,4 @@ Inactive
Last Update: $dateTool.format("YYYY-MM-dd HH:mm:ss", $lastUpdate, $locale, $timezone)
Link: $webUrl?eventId=$event.id - + diff --git a/templates/full/deviceMoving.vm b/templates/full/deviceMoving.vm index 37f3c2a93..b22b90428 100644 --- a/templates/full/deviceMoving.vm +++ b/templates/full/deviceMoving.vm @@ -7,4 +7,4 @@ Moving
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
- + diff --git a/templates/full/deviceOffline.vm b/templates/full/deviceOffline.vm index c832ee553..332bfe3d9 100644 --- a/templates/full/deviceOffline.vm +++ b/templates/full/deviceOffline.vm @@ -7,4 +7,4 @@ Offline
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Link: $webUrl?eventId=$event.id - + diff --git a/templates/full/deviceOnline.vm b/templates/full/deviceOnline.vm index fd17edef0..3ca3cfa9b 100644 --- a/templates/full/deviceOnline.vm +++ b/templates/full/deviceOnline.vm @@ -7,4 +7,4 @@ Online
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Link: $webUrl?eventId=$event.id - + diff --git a/templates/full/deviceOverspeed.vm b/templates/full/deviceOverspeed.vm index f796881a0..f303b734c 100644 --- a/templates/full/deviceOverspeed.vm +++ b/templates/full/deviceOverspeed.vm @@ -16,4 +16,4 @@ Exceeds the speed: $speedString#{if}($geofence) in $geofence.name#{else}#{end} Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
- + diff --git a/templates/full/deviceStopped.vm b/templates/full/deviceStopped.vm index 9e1e47d12..9f8a30707 100644 --- a/templates/full/deviceStopped.vm +++ b/templates/full/deviceStopped.vm @@ -7,4 +7,4 @@ Stopped
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
- + diff --git a/templates/full/deviceUnknown.vm b/templates/full/deviceUnknown.vm index 34b3a7795..0e6e9b4b4 100644 --- a/templates/full/deviceUnknown.vm +++ b/templates/full/deviceUnknown.vm @@ -7,4 +7,4 @@ Status is unknown
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Link: $webUrl?eventId=$event.id - + diff --git a/templates/full/driverChanged.vm b/templates/full/driverChanged.vm index e370d3eea..65e2768b5 100644 --- a/templates/full/driverChanged.vm +++ b/templates/full/driverChanged.vm @@ -7,4 +7,4 @@ Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezo Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
Driver: #{if}($driver)$driver.name#{else}$event.getString("driverUniqueId")#{end} - + diff --git a/templates/full/geofenceEnter.vm b/templates/full/geofenceEnter.vm index 9e00cb388..2d9cd3613 100644 --- a/templates/full/geofenceEnter.vm +++ b/templates/full/geofenceEnter.vm @@ -7,4 +7,4 @@ Has entered geofence: $geofence.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
- + diff --git a/templates/full/geofenceExit.vm b/templates/full/geofenceExit.vm index c3a300f37..ae1eb5520 100644 --- a/templates/full/geofenceExit.vm +++ b/templates/full/geofenceExit.vm @@ -7,4 +7,4 @@ Has exited geofence: $geofence.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
- + diff --git a/templates/full/ignitionOff.vm b/templates/full/ignitionOff.vm index 8a546ed29..0ec50918b 100644 --- a/templates/full/ignitionOff.vm +++ b/templates/full/ignitionOff.vm @@ -7,4 +7,4 @@ Ignition OFF
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
- + diff --git a/templates/full/ignitionOn.vm b/templates/full/ignitionOn.vm index 9ae9a63e7..7e0d6532d 100644 --- a/templates/full/ignitionOn.vm +++ b/templates/full/ignitionOn.vm @@ -7,4 +7,4 @@ Ignition ON
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
- + diff --git a/templates/full/maintenance.vm b/templates/full/maintenance.vm index 612a675f8..798de637d 100644 --- a/templates/full/maintenance.vm +++ b/templates/full/maintenance.vm @@ -7,4 +7,4 @@ Maintenance is required: $maintenance.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
- + diff --git a/templates/full/test.vm b/templates/full/test.vm index 93cbdc549..41e2f3ebd 100644 --- a/templates/full/test.vm +++ b/templates/full/test.vm @@ -4,4 +4,4 @@ Test message - + diff --git a/templates/full/textMessage.vm b/templates/full/textMessage.vm index a20dddbe0..7222b4d91 100644 --- a/templates/full/textMessage.vm +++ b/templates/full/textMessage.vm @@ -3,7 +3,7 @@ Device: $device.name
-Message: $event.getString("message")
+Message: $event.getString("message")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
- + -- cgit v1.2.3 From a61e08cb47b8294bf639ebdc0916ead031e92827 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 18:25:49 -0700 Subject: Add media events (fix #3863) --- src/main/java/org/traccar/BasePipelineFactory.java | 2 + .../traccar/handler/events/BaseEventHandler.java | 2 +- .../traccar/handler/events/MediaEventHandler.java | 47 ++++++++++++++++++++++ src/main/java/org/traccar/model/Event.java | 3 +- templates/full/media.vm | 11 +++++ templates/short/media.vm | 2 + 6 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/traccar/handler/events/MediaEventHandler.java create mode 100644 templates/full/media.vm create mode 100644 templates/short/media.vm diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 915c3f7ea..fb48f81d1 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -49,6 +49,7 @@ import org.traccar.handler.events.FuelDropEventHandler; import org.traccar.handler.events.GeofenceEventHandler; import org.traccar.handler.events.IgnitionEventHandler; import org.traccar.handler.events.MaintenanceEventHandler; +import org.traccar.handler.events.MediaEventHandler; import org.traccar.handler.events.MotionEventHandler; import org.traccar.handler.events.OverspeedEventHandler; @@ -141,6 +142,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { ComputedAttributesHandler.class, WebDataHandler.class, DefaultDataHandler.class, + MediaEventHandler.class, CommandResultEventHandler.class, OverspeedEventHandler.class, BehaviorEventHandler.class, diff --git a/src/main/java/org/traccar/handler/events/BaseEventHandler.java b/src/main/java/org/traccar/handler/events/BaseEventHandler.java index f7199f6dc..271aaa35d 100644 --- a/src/main/java/org/traccar/handler/events/BaseEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BaseEventHandler.java @@ -36,7 +36,7 @@ public abstract class BaseEventHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { Map events = analyzePosition(position); - if (events != null) { + if (events != null && !events.isEmpty()) { notificationManager.updateEvents(events); } return position; diff --git a/src/main/java/org/traccar/handler/events/MediaEventHandler.java b/src/main/java/org/traccar/handler/events/MediaEventHandler.java new file mode 100644 index 000000000..5b9013fad --- /dev/null +++ b/src/main/java/org/traccar/handler/events/MediaEventHandler.java @@ -0,0 +1,47 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.handler.events; + +import io.netty.channel.ChannelHandler; +import org.traccar.model.Event; +import org.traccar.model.Position; + +import javax.inject.Inject; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@ChannelHandler.Sharable +public class MediaEventHandler extends BaseEventHandler { + + @Inject + public MediaEventHandler() { + } + + @Override + protected Map analyzePosition(Position position) { + return Stream.of(Position.KEY_IMAGE, Position.KEY_VIDEO, Position.KEY_AUDIO) + .filter(position::hasAttribute) + .map(type -> { + Event event = new Event(Event.TYPE_MEDIA, position); + event.set("media", type); + event.set("file", position.getString(type)); + return event; + }) + .collect(Collectors.toMap(event -> event, event -> position)); + } + +} diff --git a/src/main/java/org/traccar/model/Event.java b/src/main/java/org/traccar/model/Event.java index 6e3953fda..f00a0e5f1 100644 --- a/src/main/java/org/traccar/model/Event.java +++ b/src/main/java/org/traccar/model/Event.java @@ -62,10 +62,9 @@ public class Event extends Message { public static final String TYPE_IGNITION_OFF = "ignitionOff"; public static final String TYPE_MAINTENANCE = "maintenance"; - public static final String TYPE_TEXT_MESSAGE = "textMessage"; - public static final String TYPE_DRIVER_CHANGED = "driverChanged"; + public static final String TYPE_MEDIA = "media"; private Date eventTime; diff --git a/templates/full/media.vm b/templates/full/media.vm new file mode 100644 index 000000000..6651deffc --- /dev/null +++ b/templates/full/media.vm @@ -0,0 +1,11 @@ +#set($subject = "$device.name: media file received") + + + +Device: $device.name
+Type: $event.getString("media")
+File: $event.getString("file")
+Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
+Link: $webUrl?eventId=$event.id + + diff --git a/templates/short/media.vm b/templates/short/media.vm new file mode 100644 index 000000000..783636f3f --- /dev/null +++ b/templates/short/media.vm @@ -0,0 +1,2 @@ +#set($subject = "$device.name: media file received") +$device.name $event.getString("media") received: $event.getString("file") at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) -- cgit v1.2.3 From c4509720c5dab9d7ba17dd6e89f0d846052b0c39 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Jul 2022 20:47:11 -0700 Subject: Reset start on restart --- src/main/java/org/traccar/Main.java | 6 ++++ .../org/traccar/broadcast/BroadcastService.java | 1 + .../broadcast/MulticastBroadcastService.java | 5 ++++ .../traccar/broadcast/NullBroadcastService.java | 5 ++++ .../java/org/traccar/helper/model/DeviceUtil.java | 33 ++++++++++++++++++++++ 5 files changed, 50 insertions(+) create mode 100644 src/main/java/org/traccar/helper/model/DeviceUtil.java diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 6a968ac7e..e34fbb72a 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -20,8 +20,10 @@ import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; +import org.traccar.helper.model.DeviceUtil; import org.traccar.schedule.ScheduleManager; import org.traccar.storage.DatabaseModule; +import org.traccar.storage.Storage; import org.traccar.web.WebModule; import org.traccar.web.WebServer; @@ -120,6 +122,10 @@ public final class Main { LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); LOGGER.info("Starting server..."); + if (injector.getInstance(BroadcastService.class).singleInstance()) { + DeviceUtil.resetStatus(injector.getInstance(Storage.class)); + } + var services = Stream.of( ServerManager.class, WebServer.class, ScheduleManager.class, BroadcastService.class) .map(injector::getInstance) diff --git a/src/main/java/org/traccar/broadcast/BroadcastService.java b/src/main/java/org/traccar/broadcast/BroadcastService.java index 8a2e4bafc..a86c43b5b 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastService.java +++ b/src/main/java/org/traccar/broadcast/BroadcastService.java @@ -18,5 +18,6 @@ package org.traccar.broadcast; import org.traccar.LifecycleObject; public interface BroadcastService extends LifecycleObject, BroadcastInterface { + boolean singleInstance(); void registerListener(BroadcastInterface listener); } diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index 3eafe07d3..be65b7826 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -70,6 +70,11 @@ public class MulticastBroadcastService implements BroadcastService { group = new InetSocketAddress(address, port); } + @Override + public boolean singleInstance() { + return false; + } + @Override public void registerListener(BroadcastInterface listener) { listeners.add(listener); diff --git a/src/main/java/org/traccar/broadcast/NullBroadcastService.java b/src/main/java/org/traccar/broadcast/NullBroadcastService.java index 3f41299db..f95037990 100644 --- a/src/main/java/org/traccar/broadcast/NullBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/NullBroadcastService.java @@ -17,6 +17,11 @@ package org.traccar.broadcast; public class NullBroadcastService implements BroadcastService { + @Override + public boolean singleInstance() { + return true; + } + @Override public void registerListener(BroadcastInterface listener) { } diff --git a/src/main/java/org/traccar/helper/model/DeviceUtil.java b/src/main/java/org/traccar/helper/model/DeviceUtil.java new file mode 100644 index 000000000..597078caf --- /dev/null +++ b/src/main/java/org/traccar/helper/model/DeviceUtil.java @@ -0,0 +1,33 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper.model; + +import org.traccar.model.Device; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; + +public final class DeviceUtil { + + private DeviceUtil() { + } + + public static void resetStatus(Storage storage) throws StorageException { + storage.updateObject(new Device(), new Request(new Columns.Include("status"))); + } + +} -- cgit v1.2.3 From b8ef27e67a687c27520f7a99640278f8607cdc0b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Jul 2022 08:09:23 -0700 Subject: Fix push notifications --- src/main/java/org/traccar/notificators/NotificatorTraccar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index cb8647335..123b16ad8 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -55,7 +55,7 @@ public class NotificatorTraccar implements Notificator { public NotificatorTraccar(Config config, NotificationFormatter notificationFormatter, Client client) { this.notificationFormatter = notificationFormatter; this.client = client; - this.url = "http://localhost:3001/push/"; + this.url = "https://www.traccar.org/push/"; this.key = config.getString(Keys.NOTIFICATOR_TRACCAR_KEY); } -- cgit v1.2.3 From 4d37fc1ec3c4d3ba8e9421df08bb40979b19b5db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Jul 2022 16:22:33 -0700 Subject: Fix get manager users --- src/main/java/org/traccar/api/resource/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 1bb399437..dd71de4c6 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -54,8 +54,8 @@ public class UserResource extends BaseObjectResource { @GET public Collection get(@QueryParam("userId") long userId) throws StorageException { - permissionsService.checkUser(getUserId(), userId); if (userId > 0) { + permissionsService.checkUser(getUserId(), userId); return storage.getObjects(baseClass, new Request( new Columns.All(), new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups())); -- cgit v1.2.3 From d75bda2f95081e49272d9f6cadd89b1ba398f888 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Jul 2022 16:32:12 -0700 Subject: Better ADC decoding (fix #4899) --- .../org/traccar/protocol/MeitrackProtocolDecoder.java | 15 +++++++-------- .../org/traccar/protocol/MeitrackProtocolDecoderTest.java | 4 ++++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 87459d3fc..88b7d12c8 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -211,11 +211,11 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { switch (deviceModel.toUpperCase()) { case "MVT340": case "MVT380": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.0 * 2.0 / 1024.0); + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.0 * 2.0 / 1024.0); position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.0 * 16.0 / 1024.0); break; case "MT90": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.3 * 2.0 / 4096.0); + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.3 * 2.0 / 4096.0); position.set(Position.KEY_POWER, parser.nextHexInt(0)); break; case "T1": @@ -225,19 +225,18 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case "MVT800": case "TC68": case "TC68S": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.3 * 2.0 / 4096.0); + position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.3 * 2.0 / 4096.0); position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.3 * 16.0 / 4096.0); break; case "T311": case "T322X": case "T333": case "T355": - position.set(Position.KEY_BATTERY, parser.nextHexInt(0) / 100.0); - position.set(Position.KEY_POWER, parser.nextHexInt(0) / 100.0); - break; + case "T366": + case "T366G": default: - position.set(Position.KEY_BATTERY, parser.nextHexInt(0)); - position.set(Position.KEY_POWER, parser.nextHexInt(0)); + position.set(Position.KEY_BATTERY, parser.nextHexInt() / 100.0); + position.set(Position.KEY_POWER, parser.nextHexInt(0) / 100.0); break; } diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index d4ecae10a..09ab0440d 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "$$F160,861412043027965,AAA,22,45.499458,-82.493581,220718171428,V,0,0,0,0,0.0,0,227940,119812,302|220|D8D6|086E1B2B,0000,0000|0000|0000|0191|0573,,,3,,002134,0,0*FA"), + Position.KEY_POWER, 13.95); + verifyPositions(decoder, binary( "2424423233392c3836323039303035303030373436352c4343452c0100000003004300130006050006000700140015801b00080800000900000a00000b0000165105198d011a630540160005024c5e910103590bfe0204922153290c6b2501000dd5b50200004300130006050006000700140015011b00080800000900000a00000b0000165005198d011a630540010005024c5e910103590bfe0204932153290c6b2501000dd6b50200004300130006050006000700140015011b00080800000900000a00000b0000165205198d011a630540230005024c5e910103590bfe0204942153290c6b2501000dd7b50200002a43330d0a")); -- cgit v1.2.3 From 35070c85e26fe75e73315506b8cae3360f79d12e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 19 Jul 2022 18:45:02 -0700 Subject: Add coordinates validation --- src/main/java/org/traccar/model/Position.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index d6c985458..2b743433a 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -227,7 +227,9 @@ public class Position extends Message { } public void setLatitude(double latitude) { - this.latitude = latitude; + if (latitude >= -90 && latitude <= 90) { + this.latitude = latitude; + } } private double longitude; @@ -237,7 +239,9 @@ public class Position extends Message { } public void setLongitude(double longitude) { - this.longitude = longitude; + if (longitude >= -180 && longitude <= 180) { + this.longitude = longitude; + } } private double altitude; // value in meters -- cgit v1.2.3 From 482876a5d8f4ba2e749aa5b39c29cd07589f7bcc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Jul 2022 16:55:02 -0700 Subject: Add Xexun2 dismantle alarm --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 501897715..a572f8622 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -67,6 +67,9 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(value, 0)) { return Position.ALARM_SOS; } + if (BitUtil.check(value, 1)) { + return Position.ALARM_REMOVING; + } if (BitUtil.check(value, 15)) { return Position.ALARM_FALL_DOWN; } -- cgit v1.2.3 From d42f935e4119fb87002b8b275c4237290ef7f12b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Jul 2022 18:21:31 -0700 Subject: Fix duplicate notifications --- src/main/java/org/traccar/session/cache/CacheManager.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 0865b2647..07f27d776 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -42,6 +42,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -65,7 +66,7 @@ public class CacheManager implements BroadcastInterface { private final Map deviceCache = new HashMap<>(); private final Map deviceReferences = new HashMap<>(); - private final Map, List>> deviceLinks = new HashMap<>(); + private final Map, Set>> deviceLinks = new HashMap<>(); private final Map devicePositions = new HashMap<>(); private Server server; @@ -271,7 +272,7 @@ public class CacheManager implements BroadcastInterface { } private void unsafeAddDevice(long deviceId) throws StorageException { - Map, List> links = new HashMap<>(); + Map, Set> links = new HashMap<>(); Device device = storage.getObject(Device.class, new Request( new Columns.All(), new Condition.Equals("id", "id", deviceId))); @@ -283,7 +284,7 @@ public class CacheManager implements BroadcastInterface { while (groupDepth < GROUP_DEPTH_LIMIT && groupId > 0) { Group group = storage.getObject(Group.class, new Request( new Columns.All(), new Condition.Equals("id", "id", groupId))); - links.computeIfAbsent(Group.class, k -> new LinkedList<>()).add(group.getId()); + links.computeIfAbsent(Group.class, k -> new LinkedHashSet<>()).add(group.getId()); addObject(deviceId, group); groupId = group.getGroupId(); groupDepth += 1; @@ -292,13 +293,13 @@ public class CacheManager implements BroadcastInterface { for (Class clazz : CLASSES) { var objects = storage.getObjects(clazz, new Request( new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); - links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toList())); + links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toSet())); objects.forEach(object -> addObject(deviceId, object)); } var users = storage.getObjects(User.class, new Request( new Columns.All(), new Condition.Permission(User.class, Device.class, deviceId))); - links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toList())); + links.put(User.class, users.stream().map(BaseModel::getId).collect(Collectors.toSet())); for (var user : users) { addObject(deviceId, user); var notifications = storage.getObjects(Notification.class, new Request( @@ -306,7 +307,7 @@ public class CacheManager implements BroadcastInterface { notifications.stream() .filter(Notification::getAlways) .forEach(object -> { - links.computeIfAbsent(Notification.class, k -> new LinkedList<>()).add(object.getId()); + links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()).add(object.getId()); addObject(deviceId, object); }); } -- cgit v1.2.3 From 9c9af1e02ab7fea6465bf83b9b10d13197184e3d Mon Sep 17 00:00:00 2001 From: Luiz Kill Date: Thu, 21 Jul 2022 12:01:54 -0300 Subject: Fixes passwordReset.vm template Adds the reset-password endpoint to the reset link. --- templates/full/passwordReset.vm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/full/passwordReset.vm b/templates/full/passwordReset.vm index fe692ba1d..45c88f5b3 100644 --- a/templates/full/passwordReset.vm +++ b/templates/full/passwordReset.vm @@ -3,6 +3,6 @@ To reset password please click on the following link:
-$webUrl?passwordReset=$token
+$webUrl?passwordReset=$token
-- cgit v1.2.3 From eb8d5c2d83a6aa91e0932382a852a3f4aca33120 Mon Sep 17 00:00:00 2001 From: Luiz Kill Date: Thu, 21 Jul 2022 13:55:55 -0300 Subject: Adds Pushover user attributes The Pushover integration doesn't allow messages to be delivered per-user, since the NOTIFICATOR_PUSHOVER_USER config is single for the whole instance. --- .../traccar/notificators/NotificatorPushover.java | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 671984f86..0604c49f3 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -56,25 +56,24 @@ public class NotificatorPushover implements Notificator { url = "https://api.pushover.net/1/messages.json"; token = config.getString(Keys.NOTIFICATOR_PUSHOVER_TOKEN); user = config.getString(Keys.NOTIFICATOR_PUSHOVER_USER); - if (token == null || user == null) { - throw new RuntimeException("Pushover token or user missing"); - } } @Override public void send(User user, Event event, Position position) { - - String device = ""; - if (user.hasAttribute("notificator.pushover.device")) { - device = user.getString("notificator.pushover.device").replaceAll(" *, *", ","); - } - var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); Message message = new Message(); message.token = token; - message.user = this.user; - message.device = device; + + message.user = user.getString("pushoverUserKey"); + if (message.user == null) { + message.user = this.user; + } + + if (user.hasAttribute("pushoverDeviceNames")) { + message.device = user.getString("pushoverDeviceNames").replaceAll(" *, *", ","); + } + message.title = shortMessage.getSubject(); message.message = shortMessage.getBody(); -- cgit v1.2.3 From ea68646e6572945db82bfdf8e732957492e19b03 Mon Sep 17 00:00:00 2001 From: Luiz Kill Date: Thu, 21 Jul 2022 14:12:50 -0300 Subject: Fixes trailing spaces issue --- src/main/java/org/traccar/notificators/NotificatorPushover.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 0604c49f3..105cb27f0 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -64,7 +64,7 @@ public class NotificatorPushover implements Notificator { Message message = new Message(); message.token = token; - + message.user = user.getString("pushoverUserKey"); if (message.user == null) { message.user = this.user; -- cgit v1.2.3 From bf9b8c9562587476a919e095a4adc6c00bb2cba8 Mon Sep 17 00:00:00 2001 From: stefanclark Date: Thu, 21 Jul 2022 21:21:13 +0100 Subject: Update Xexun2ProtocolDecoder.java --- .../java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index a572f8622..42fa7d8f2 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -176,7 +176,19 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.setLongitude(convertCoordinate(buf.readDouble())); position.setLatitude(convertCoordinate(buf.readDouble())); - + } + if (BitUtil.check(positionMask, 7)) { + buf.skipBytes(2); // length = 30 + buf.skipBytes(1); // marker = 'G' + buf.skipBytes(2); // length = 27 + position.setLongitude(convertCoordinate(buf.readDouble())); + position.setLatitude(convertCoordinate(buf.readDouble())); + position.setValid(buf.readUnsignedByte()>0); // 0=invalid,1=normal,2=sub-meter,3=differential + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + buf.skipBytes(1); // SNR + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); + position.setCourse(buf.readUnsignedShort() * 0.1); + position.setAltitude(buf.readFloat()); } } if (BitUtil.check(mask, 3)) { -- cgit v1.2.3 From df974772a6cab1f1bdbad4c6b19e150c2ca3ccf6 Mon Sep 17 00:00:00 2001 From: stefanclark Date: Thu, 21 Jul 2022 21:56:49 +0100 Subject: Update Xexun2ProtocolDecoder.java --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 42fa7d8f2..47d86aeb1 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -183,7 +183,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(2); // length = 27 position.setLongitude(convertCoordinate(buf.readDouble())); position.setLatitude(convertCoordinate(buf.readDouble())); - position.setValid(buf.readUnsignedByte()>0); // 0=invalid,1=normal,2=sub-meter,3=differential + position.setValid(buf.readUnsignedByte() > 0); // 0=invalid,1=normal,2=sub-meter,3=differential position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); buf.skipBytes(1); // SNR position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); -- cgit v1.2.3 From c85bcf1966e690d8af56d0eff51dbae5c025340e Mon Sep 17 00:00:00 2001 From: stefanclark Date: Thu, 21 Jul 2022 22:30:46 +0100 Subject: Update Xexun2ProtocolDecoder.java --- .../traccar/protocol/Xexun2ProtocolDecoder.java | 30 ++++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 47d86aeb1..3f37d7cac 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -178,17 +178,25 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { position.setLatitude(convertCoordinate(buf.readDouble())); } if (BitUtil.check(positionMask, 7)) { - buf.skipBytes(2); // length = 30 - buf.skipBytes(1); // marker = 'G' - buf.skipBytes(2); // length = 27 - position.setLongitude(convertCoordinate(buf.readDouble())); - position.setLatitude(convertCoordinate(buf.readDouble())); - position.setValid(buf.readUnsignedByte() > 0); // 0=invalid,1=normal,2=sub-meter,3=differential - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - buf.skipBytes(1); // SNR - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); - position.setCourse(buf.readUnsignedShort() * 0.1); - position.setAltitude(buf.readFloat()); + if (buf.readUnsignedShort() > 0) { + if (buf.readByte() != 'G') { + buf.skipBytes(buf.readUnsignedShort()); + } else { + int gpsDataLen = buf.readUnsignedShort(); + if (gpsDataLen != 27) { + buf.skipBytes(gpsDataLen); + } else { + position.setLongitude(convertCoordinate(buf.readDouble())); + position.setLatitude(convertCoordinate(buf.readDouble())); + position.setValid(buf.readUnsignedByte() > 0); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + buf.readUnsignedByte(1); // satellite signal to noise ratio + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); + position.setCourse(buf.readUnsignedShort() * 0.1); + position.setAltitude(buf.readFloat()); + } + } + } } } if (BitUtil.check(mask, 3)) { -- cgit v1.2.3 From 1b07425955baf2c37216a05a0fdf6afe6258f6d7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Jul 2022 15:38:31 -0700 Subject: Add Arknav UDP support (fix #4708) --- src/main/java/org/traccar/protocol/ArknavProtocol.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/ArknavProtocol.java b/src/main/java/org/traccar/protocol/ArknavProtocol.java index ed38f26d7..4f443aa3a 100644 --- a/src/main/java/org/traccar/protocol/ArknavProtocol.java +++ b/src/main/java/org/traccar/protocol/ArknavProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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,6 +38,15 @@ public class ArknavProtocol extends BaseProtocol { pipeline.addLast(new ArknavProtocolDecoder(ArknavProtocol.this)); } }); + addServer(new TrackerServer(config, getName(), true) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new ArknavProtocolDecoder(ArknavProtocol.this)); + } + }); + } } -- cgit v1.2.3 From 89a32633c1bd9119990b7b9070a1ba04e1eb0ea4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Jul 2022 18:34:33 -0700 Subject: Remove double assignment --- src/main/java/org/traccar/protocol/UproProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java index bdc6bf24e..f23274a8f 100644 --- a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java @@ -67,7 +67,6 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - position.setValid(true); position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); -- cgit v1.2.3 From 033e50725806fdd5597e37a24eff763800e1cdfa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Jul 2022 18:36:12 -0700 Subject: Fix validity decoding --- src/main/java/org/traccar/protocol/UproProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java index f23274a8f..ed714e464 100644 --- a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java @@ -71,7 +71,7 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); int flags = parser.nextInt(0); - position.setValid(BitUtil.check(flags, 0)); + position.setValid(!BitUtil.check(flags, 0)); if (!BitUtil.check(flags, 1)) { position.setLatitude(-position.getLatitude()); } -- cgit v1.2.3 From 4c03090e81d15d328f51546ef518e7b8823c0fa6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Jul 2022 18:43:43 -0700 Subject: Fix unit tests --- src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java index 3464a6fee..8d32eebb1 100644 --- a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java @@ -53,7 +53,7 @@ public class UproProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, buffer( "*MG201693502000034964,AB&A0800253335360507036975710000091116&P0730000032d2a94d&B0000000000&N13&Z12&U_P\0\0\0\u0004\0\0\0\0\0\0\0\0\0\0"), - position("2016-11-09 08:00:25.000", true, -33.58934, -70.61626)); + position("2016-11-09 08:00:25.000", false, -33.58934, -70.61626)); verifyNull(decoder, buffer( "*MG20113800138000,AH")); @@ -69,7 +69,7 @@ public class UproProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, buffer( "*AI200905300036,AH&A0317264913209801844913060000251115&B0500000000&C0;4?72:9&F0000"), - position("2015-11-25 03:17:26.000", false, 49.22016, 18.74855)); + position("2015-11-25 03:17:26.000", true, 49.22016, 18.74855)); verifyPosition(decoder, buffer( "*AI2000905300036,AS&A1647304913209801844913060000251115&B0400000000&C0;4?72:9&F0000")); -- cgit v1.2.3 From 708f04be5d9a25bd9d217127680a61f307cb8ef2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 21 Jul 2022 18:45:13 -0700 Subject: Fix password reset link text --- templates/full/passwordReset.vm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/full/passwordReset.vm b/templates/full/passwordReset.vm index 45c88f5b3..38da10aa3 100644 --- a/templates/full/passwordReset.vm +++ b/templates/full/passwordReset.vm @@ -3,6 +3,6 @@ To reset password please click on the following link:
-$webUrl?passwordReset=$token
+$webUrl/modern/reset-password?passwordReset=$token
-- cgit v1.2.3 From 4a10f75f016af996bd15e90101f0d20e4d61e083 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 22 Jul 2022 17:33:40 -0700 Subject: Add device expiration (fix #3056, fix #3529) --- schema/changelog-5.3.xml | 4 +++ .../org/traccar/api/security/LoginService.java | 7 +--- src/main/java/org/traccar/model/Device.java | 16 ++++++++- src/main/java/org/traccar/model/Disableable.java | 39 ++++++++++++++++++++++ src/main/java/org/traccar/model/User.java | 6 +++- .../org/traccar/session/ConnectionManager.java | 6 ++-- 6 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/traccar/model/Disableable.java diff --git a/schema/changelog-5.3.xml b/schema/changelog-5.3.xml index b574a67d2..063046ce9 100644 --- a/schema/changelog-5.3.xml +++ b/schema/changelog-5.3.xml @@ -16,6 +16,10 @@ + + + + diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 9938cf6dc..104a6fac3 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -83,12 +83,7 @@ public class LoginService { if (user == null) { throw new SecurityException("Unknown account"); } - if (user.getDisabled()) { - throw new SecurityException("Account is disabled"); - } - if (user.getExpirationTime() != null && System.currentTimeMillis() > user.getExpirationTime().getTime()) { - throw new SecurityException("Account has expired"); - } + user.checkDisabled(); } } diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 57ba07624..f21e5ca84 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -23,7 +23,7 @@ import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @StorageName("tc_devices") -public class Device extends GroupedModel { +public class Device extends GroupedModel implements Disableable { private String name; @@ -140,12 +140,26 @@ public class Device extends GroupedModel { private boolean disabled; + @Override public boolean getDisabled() { return disabled; } + @Override public void setDisabled(boolean disabled) { this.disabled = disabled; } + private Date expirationTime; + + @Override + public Date getExpirationTime() { + return expirationTime; + } + + @Override + public void setExpirationTime(Date expirationTime) { + this.expirationTime = expirationTime; + } + } diff --git a/src/main/java/org/traccar/model/Disableable.java b/src/main/java/org/traccar/model/Disableable.java new file mode 100644 index 000000000..1145d6279 --- /dev/null +++ b/src/main/java/org/traccar/model/Disableable.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.model; + +import java.util.Date; + +public interface Disableable { + + boolean getDisabled(); + + void setDisabled(boolean disabled); + + Date getExpirationTime(); + + void setExpirationTime(Date expirationTime); + + default void checkDisabled() throws SecurityException { + if (getDisabled()) { + throw new SecurityException(getClass().getSimpleName() + " is disabled"); + } + if (getExpirationTime() != null && System.currentTimeMillis() > getExpirationTime().getTime()) { + throw new SecurityException(getClass().getSimpleName() + " has expired"); + } + } + +} diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 0aa67168f..3db20c753 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -24,7 +24,7 @@ import org.traccar.storage.StorageName; import java.util.Date; @StorageName("tc_users") -public class User extends ExtendedModel implements UserRestrictions { +public class User extends ExtendedModel implements UserRestrictions, Disableable { private String name; @@ -155,20 +155,24 @@ public class User extends ExtendedModel implements UserRestrictions { private boolean disabled; + @Override public boolean getDisabled() { return disabled; } + @Override public void setDisabled(boolean disabled) { this.disabled = disabled; } private Date expirationTime; + @Override public Date getExpirationTime() { return expirationTime; } + @Override public void setExpirationTime(Date expirationTime) { this.expirationTime = expirationTime; } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 9888cca2b..2d183ee22 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -136,7 +136,9 @@ public class ConnectionManager implements BroadcastInterface { device = addUnknownDevice(uniqueIds[0]); } - if (device != null && !device.getDisabled()) { + if (device != null) { + device.checkDisabled(); + DeviceSession oldSession = sessionsByDeviceId.remove(device.getId()); if (oldSession != null) { Endpoint oldEndpoint = new Endpoint(oldSession.getChannel(), oldSession.getRemoteAddress()); @@ -160,7 +162,7 @@ public class ConnectionManager implements BroadcastInterface { return deviceSession; } else { - LOGGER.warn((device == null ? "Unknown" : "Disabled") + " device - " + String.join(" ", uniqueIds) + LOGGER.warn("Unknown device - " + String.join(" ", uniqueIds) + " (" + ((InetSocketAddress) remoteAddress).getHostString() + ")"); return null; } -- cgit v1.2.3 From 0242c8c9a2983ed2e082bb64d7941b4d345aa734 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Sat, 23 Jul 2022 08:28:00 +0000 Subject: Added test csse & updated code for Xexun2ProtocolDecoder --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 11 +++++++---- .../java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 3f37d7cac..402095391 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -178,22 +178,25 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { position.setLatitude(convertCoordinate(buf.readDouble())); } if (BitUtil.check(positionMask, 7)) { - if (buf.readUnsignedShort() > 0) { + int dataLength = buf.readUnsignedShort(); + if (dataLength > 0) { if (buf.readByte() != 'G') { - buf.skipBytes(buf.readUnsignedShort()); + buf.skipBytes(dataLength - 1); } else { int gpsDataLen = buf.readUnsignedShort(); if (gpsDataLen != 27) { - buf.skipBytes(gpsDataLen); + buf.skipBytes(dataLength - 3); } else { + position.setFixTime(position.getDeviceTime()); position.setLongitude(convertCoordinate(buf.readDouble())); position.setLatitude(convertCoordinate(buf.readDouble())); position.setValid(buf.readUnsignedByte() > 0); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - buf.readUnsignedByte(1); // satellite signal to noise ratio + buf.readUnsignedByte(); // satellite signal to noise ratio position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort() * 0.1); position.setAltitude(buf.readFloat()); + buf.skipBytes(dataLength - 30); } } } diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java index 840c38b52..215b90c66 100644 --- a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java @@ -25,6 +25,9 @@ public class Xexun2ProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "FAAF00140CF18626490454584530002BF2DD0200130013D360EFD7F514006402010D46322C4A450BA026D460EFD7FA14006402010D46322C4A450BA026FAAF")); + verifyPositions(decoder, binary( + "FAAF0014000C8622050512345670002DF3A001002A0062D9047400005E0280001E47001B400D4BA732DF505E40B4153AAF78FEF00109000000000042B36666FAAF")); + } } -- cgit v1.2.3 From 14dafcb4191ec25fa22494956cd509708a9e1b5c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 23 Jul 2022 07:57:02 -0700 Subject: Improve Xexun2 decoder --- .../traccar/protocol/Xexun2ProtocolDecoder.java | 31 +++++++++------------- .../protocol/Xexun2ProtocolDecoderTest.java | 3 ++- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 402095391..28e7fbda3 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -180,25 +180,20 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(positionMask, 7)) { int dataLength = buf.readUnsignedShort(); if (dataLength > 0) { - if (buf.readByte() != 'G') { - buf.skipBytes(dataLength - 1); - } else { - int gpsDataLen = buf.readUnsignedShort(); - if (gpsDataLen != 27) { - buf.skipBytes(dataLength - 3); - } else { - position.setFixTime(position.getDeviceTime()); - position.setLongitude(convertCoordinate(buf.readDouble())); - position.setLatitude(convertCoordinate(buf.readDouble())); - position.setValid(buf.readUnsignedByte() > 0); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - buf.readUnsignedByte(); // satellite signal to noise ratio - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); - position.setCourse(buf.readUnsignedShort() * 0.1); - position.setAltitude(buf.readFloat()); - buf.skipBytes(dataLength - 30); - } + int dataType = buf.readUnsignedByte(); + int dataEndIndex = buf.readerIndex() + buf.readUnsignedShort(); + if (dataType == 'G') { + position.setFixTime(position.getDeviceTime()); + position.setLongitude(convertCoordinate(buf.readDouble())); + position.setLatitude(convertCoordinate(buf.readDouble())); + position.setValid(buf.readUnsignedByte() > 0); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + buf.readUnsignedByte(); // satellite signal-to-noise ratio + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); + position.setCourse(buf.readUnsignedShort() * 0.1); + position.setAltitude(buf.readFloat()); } + buf.readerIndex(dataEndIndex); } } } diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java index 215b90c66..48ba1a691 100644 --- a/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolDecoderTest.java @@ -26,7 +26,8 @@ public class Xexun2ProtocolDecoderTest extends ProtocolTest { "FAAF00140CF18626490454584530002BF2DD0200130013D360EFD7F514006402010D46322C4A450BA026D460EFD7FA14006402010D46322C4A450BA026FAAF")); verifyPositions(decoder, binary( - "FAAF0014000C8622050512345670002DF3A001002A0062D9047400005E0280001E47001B400D4BA732DF505E40B4153AAF78FEF00109000000000042B36666FAAF")); + "FAAF0014000C8622050512345670002DF3A001002A0062D9047400005E0280001E47001B400D4BA732DF505E40B4153AAF78FEF00109000000000042B36666FAAF"), + position("2022-07-21 07:47:00.000", true, 51.68715, 0.06103)); } -- cgit v1.2.3 From 4a24779dd6e72247dde96127791ab1f5055b1b53 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 23 Jul 2022 11:52:34 -0700 Subject: Improve iStartek decoding --- .../traccar/protocol/StartekProtocolDecoder.java | 38 +++++++++++++--------- .../protocol/StartekProtocolDecoderTest.java | 6 +++- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index 53c02f28c..b2fcd5452 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -42,6 +42,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .number("d+,") // length .number("(d+),") // imei .expression("(.+)") // content + .number("xx") // checksum .compile(); private static final Pattern PATTERN_POSITION = new PatternBuilder() @@ -73,22 +74,26 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .groupBegin() .text(",") .number("d,") // extended - .expression("([^,]+)?,") // fuel + .expression("([^,]+)?") // fuel + .groupBegin() + .text(",") .expression("([^,]+)?") // temperature .groupBegin() .text(",") - .number("(d+)|") // rpm - .number("(d+)|") // engine load - .number("d+|") // maf flow - .number("d+|") // intake pressure - .number("d+|") // intake temperature - .number("(d+)|") // throttle - .number("(d+)|") // coolant temperature - .number("(d+)|") // instant fuel - .number("(d+)") // fuel level + .groupBegin() + .number("(d+)?|") // rpm + .number("(d+)?|") // engine load + .number("d*|") // maf flow + .number("d*|") // intake pressure + .number("d*|") // intake temperature + .number("(d+)?|") // throttle + .number("(d+)?|") // coolant temperature + .number("(d+)?|") // instant fuel + .number("(d+)[%L]").optional() // fuel level + .groupEnd("?") + .groupEnd("?") .groupEnd("?") .groupEnd("?") - .any() .compile(); private String decodeAlarm(int value) { @@ -122,9 +127,6 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { } String content = parser.next(); - if (content.charAt(content.length() - 2 - 1) != '|') { - content = content.substring(0, content.length() - 2); - } if (content.length() < 100) { Position position = new Position(getProtocolName()); @@ -223,8 +225,12 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RPM, parser.nextInt()); position.set(Position.KEY_ENGINE_LOAD, parser.nextInt()); position.set(Position.KEY_THROTTLE, parser.nextInt()); - position.set(Position.KEY_COOLANT_TEMP, parser.nextInt() - 40); - position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextInt() * 0.1); + if (parser.hasNext()) { + position.set(Position.KEY_COOLANT_TEMP, parser.nextInt() - 40); + } + if (parser.hasNext()) { + position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextInt() * 0.1); + } position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); } diff --git a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java index e8eecae96..072c19942 100644 --- a/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/StartekProtocolDecoderTest.java @@ -11,9 +11,13 @@ public class StartekProtocolDecoderTest extends ProtocolTest { var decoder = inject(new StartekProtocolDecoder(null)); + verifyAttribute(decoder, text( + "&&x164,869926040743375,000,0,,220705205955,A,33.326001,44.445318,10,1.2,0,57,8,925,418|40|038C|000083CD,31,00000015,00,00,0016|016A|0000|0000,1,,,686|33||44|99|14|124|11|8D"), + Position.KEY_FUEL_CONSUMPTION, 1.1); + verifyAttribute(decoder, text( "&&R187,860294046453690,000,0,,220105160656,A,22.994986,72.499711,15,0.9,2,222,55,121135784,404|98|147B|0000376A,24,0000001F,02,00,052E|01A3|0000|0000,1,010000|020000,,853|6|10|105|73|41|125|34|52"), - Position.KEY_FUEL_LEVEL, 52); + Position.KEY_FUEL_LEVEL, null); verifyPosition(decoder, text( "&&o142,860262050066062,000,27,,211111070826,V,28.653435,-106.077455,0,0.0,0,151,1412,918,0|0|4708|01402D19,6,0000001A,02,00,04C0|016C|0000|0000,1,,,BB")); -- cgit v1.2.3 From 929240716f09627de9823d411a11fc0cdf6eb49b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Jul 2022 09:09:17 -0700 Subject: Fix group permissions --- .../java/org/traccar/storage/DatabaseStorage.java | 28 ++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index eec72b510..8ca464147 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -355,41 +355,45 @@ public class DatabaseStorage extends Storage { result.append("SELECT DISTINCT "); if (!expandDevices) { - result.append(groupStorageName).append('.'); + if (outputKey.equals("groupId")) { + result.append("all_groups."); + } else { + result.append(groupStorageName).append('.'); + } } result.append(outputKey); result.append(" FROM "); result.append(groupStorageName); result.append(" INNER JOIN ("); - result.append("SELECT id as parentid, id as groupid FROM "); + result.append("SELECT id as parentId, id as groupId FROM "); result.append(getStorageName(Group.class)); result.append(" UNION "); - result.append("SELECT groupid as parentid, id as groupid FROM "); + result.append("SELECT groupId as parentId, id as groupId FROM "); result.append(getStorageName(Group.class)); - result.append(" WHERE groupid IS NOT NULL"); + result.append(" WHERE groupId IS NOT NULL"); result.append(" UNION "); - result.append("SELECT g2.groupid as parentid, g1.id as groupid FROM "); + result.append("SELECT g2.groupId as parentId, g1.id as groupId FROM "); result.append(getStorageName(Group.class)); result.append(" AS g2"); result.append(" INNER JOIN "); result.append(getStorageName(Group.class)); - result.append(" AS g1 ON g2.id = g1.groupid"); - result.append(" WHERE g2.groupid IS NOT NULL"); + result.append(" AS g1 ON g2.id = g1.groupId"); + result.append(" WHERE g2.groupId IS NOT NULL"); result.append(") AS all_groups ON "); result.append(groupStorageName); - result.append(".groupid = all_groups.parentid"); + result.append(".groupId = all_groups.parentId"); if (expandDevices) { result.append(" INNER JOIN ("); - result.append("SELECT groupid as parentid, id as deviceid FROM "); + result.append("SELECT groupId as parentId, id as deviceId FROM "); result.append(getStorageName(Device.class)); - result.append(" WHERE groupid IS NOT NULL"); - result.append(") AS devices ON all_groups.groupid = devices.parentid"); + result.append(" WHERE groupId IS NOT NULL"); + result.append(") AS devices ON all_groups.groupId = devices.parentId"); } result.append(" WHERE "); - result.append(conditionKey); // TODO handle search for device / group + result.append(conditionKey); result.append(" = :"); result.append(conditionKey); -- cgit v1.2.3 From eb39a38711c924ae0ecc7ad29ad69e74a95d92d8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Jul 2022 14:07:51 -0700 Subject: Avoid copying array --- src/main/java/org/traccar/model/Calendar.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/model/Calendar.java b/src/main/java/org/traccar/model/Calendar.java index 102c0be52..c1f98a957 100644 --- a/src/main/java/org/traccar/model/Calendar.java +++ b/src/main/java/org/traccar/model/Calendar.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2016 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,13 +49,13 @@ public class Calendar extends ExtendedModel { private byte[] data; public byte[] getData() { - return data.clone(); + return data; } public void setData(byte[] data) throws IOException, ParserException { CalendarBuilder builder = new CalendarBuilder(); calendar = builder.build(new ByteArrayInputStream(data)); - this.data = data.clone(); + this.data = data; } private net.fortuna.ical4j.model.Calendar calendar; -- cgit v1.2.3 From 2daec980de3183efbefc3e79a914a01dc6de910b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Jul 2022 15:42:23 -0700 Subject: Improve query builder --- src/main/java/org/traccar/storage/QueryBuilder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index 910ebf170..a58ebe2b4 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -288,7 +288,8 @@ public final class QueryBuilder { Method[] methods = object.getClass().getMethods(); for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { + if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 + && !method.getName().equals("getClass")) { String name = method.getName().substring(3); try { if (method.getReturnType().equals(boolean.class)) { -- cgit v1.2.3 From bcd902eaf972ec4cd2befeec0ee0ab0940b7d711 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Jul 2022 15:47:45 -0700 Subject: Crypto signatures support --- schema/changelog-5.3.xml | 12 +++ .../org/traccar/api/signature/CryptoManager.java | 98 ++++++++++++++++++++++ .../org/traccar/api/signature/KeystoreModel.java | 44 ++++++++++ 3 files changed, 154 insertions(+) create mode 100644 src/main/java/org/traccar/api/signature/CryptoManager.java create mode 100644 src/main/java/org/traccar/api/signature/KeystoreModel.java diff --git a/schema/changelog-5.3.xml b/schema/changelog-5.3.xml index 063046ce9..a689bc236 100644 --- a/schema/changelog-5.3.xml +++ b/schema/changelog-5.3.xml @@ -20,6 +20,18 @@ + + + + + + + + + + + + diff --git a/src/main/java/org/traccar/api/signature/CryptoManager.java b/src/main/java/org/traccar/api/signature/CryptoManager.java new file mode 100644 index 000000000..ea59dcd70 --- /dev/null +++ b/src/main/java/org/traccar/api/signature/CryptoManager.java @@ -0,0 +1,98 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.api.signature; + +import org.traccar.helper.DataConverter; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +public class CryptoManager { + + private final Storage storage; + + private PublicKey publicKey; + private PrivateKey privateKey; + + @Inject + public CryptoManager(Storage storage) { + this.storage = storage; + } + + public String sign(String data) throws GeneralSecurityException, StorageException { + if (privateKey == null) { + initializeKeys(); + } + Signature signature = Signature.getInstance("SHA256withECDSA"); + signature.initSign(privateKey); + signature.update(data.getBytes()); + return data + '.' + DataConverter.printBase64(signature.sign()); + } + + public String verify(String data) throws GeneralSecurityException, StorageException { + if (publicKey == null) { + initializeKeys(); + } + Signature signature = Signature.getInstance("SHA256withECDSA"); + signature.initVerify(publicKey); + + int delimiter = data.lastIndexOf('.'); + String originalData = data.substring(0, delimiter); + + signature.update(originalData.getBytes()); + if (!signature.verify(DataConverter.parseBase64(data.substring(delimiter + 1)))) { + throw new SecurityException("Invalid signature"); + } + return originalData; + } + + private void initializeKeys() throws StorageException, GeneralSecurityException { + KeystoreModel model = storage.getObject(KeystoreModel.class, new Request(new Columns.All())); + if (model != null) { + publicKey = KeyFactory.getInstance("EC") + .generatePublic(new X509EncodedKeySpec(model.getPublicKey())); + privateKey = KeyFactory.getInstance("EC") + .generatePrivate(new PKCS8EncodedKeySpec(model.getPrivateKey())); + } else { + KeyPairGenerator generator = KeyPairGenerator.getInstance("EC"); + generator.initialize(new ECGenParameterSpec("secp256r1"), new SecureRandom()); + KeyPair pair = generator.generateKeyPair(); + + publicKey = pair.getPublic(); + privateKey = pair.getPrivate(); + + model = new KeystoreModel(); + model.setPublicKey(publicKey.getEncoded()); + model.setPrivateKey(privateKey.getEncoded()); + storage.addObject(model, new Request(new Columns.Exclude("id"))); + } + } + +} diff --git a/src/main/java/org/traccar/api/signature/KeystoreModel.java b/src/main/java/org/traccar/api/signature/KeystoreModel.java new file mode 100644 index 000000000..7f3140e81 --- /dev/null +++ b/src/main/java/org/traccar/api/signature/KeystoreModel.java @@ -0,0 +1,44 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.api.signature; + +import org.traccar.model.BaseModel; +import org.traccar.storage.StorageName; + +@StorageName("tc_keystore") +public class KeystoreModel extends BaseModel { + + private byte[] publicKey; + + public byte[] getPublicKey() { + return publicKey; + } + + public void setPublicKey(byte[] publicKey) { + this.publicKey = publicKey; + } + + private byte[] privateKey; + + public byte[] getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(byte[] privateKey) { + this.privateKey = privateKey; + } + +} -- cgit v1.2.3 From 5ee3d373993f85b37213b0d21818144b481d2045 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Jul 2022 16:29:29 -0700 Subject: Update jersey and jackson --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 36fc2f6df..135654c9d 100644 --- a/build.gradle +++ b/build.gradle @@ -12,8 +12,8 @@ repositories { ext { guiceVersion = "5.0.1" jettyVersion = "10.0.7" // jetty 11 javax to jakarta - jerseyVersion = "2.35" // jersey 3 javax to jakarta - jacksonVersion = "2.12.2" // same version as jersey-media-json-jackson dependency + jerseyVersion = "2.36" // jersey 3 javax to jakarta + jacksonVersion = "2.13.3" // same version as jersey-media-json-jackson dependency protobufVersion = "3.19.3" } -- cgit v1.2.3 From 032d02b584553f4374c4bc6ae9f7c8e819595c42 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 06:50:59 +0000 Subject: Xexun2 Encoder - Initial Code --- .../java/org/traccar/protocol/Xexun2Protocol.java | 7 ++ .../traccar/protocol/Xexun2ProtocolEncoder.java | 121 +++++++++++++++++++++ .../protocol/Xexun2ProtocolEncoderTest.java | 29 +++++ 3 files changed, 157 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java create mode 100644 src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index 4630a69e0..1d5038a22 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -19,6 +19,7 @@ import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import org.traccar.model.Command; import javax.inject.Inject; @@ -26,11 +27,17 @@ public class Xexun2Protocol extends BaseProtocol { @Inject public Xexun2Protocol(Config config) { + setSupportedDataCommands( + Command.TYPE_CUSTOM, + Command.TYPE_POSITION_PERIODIC, + Command.TYPE_POWER_OFF, + Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xexun2FrameDecoder()); pipeline.addLast(new Xexun2ProtocolDecoder(Xexun2Protocol.this)); + pipeline.addLast(new Xexun2ProtocolEncoder(Xexun2Protocol.this)); } }); } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java new file mode 100644 index 000000000..d85c6734b --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -0,0 +1,121 @@ +/* + * Copyright 2016 - 2022 Anton Tananaev (anton@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 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; + +public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { + + public Xexun2ProtocolEncoder(Protocol protocol) { + super(protocol); + } + + private static ByteBuf encodeFrame(ByteBuf buf) { + buf.clear(); + if (buf.readableBytes() < 5) { + return null; + } + + ByteBuf result = Unpooled.buffer(); + + result.writeBytes(buf.readBytes(2)); + + while (buf.readerIndex() < buf.capacity() - 2) { + int b = buf.readUnsignedByte(); + if (b == 0xfa && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xaf) { + buf.readUnsignedByte(); + result.writeByte(0xfb); + result.writeByte(0xbf); + result.writeByte(0x01); + } else if (b == 0xfb && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xbf) { + buf.readUnsignedByte(); + result.writeByte(0xfb); + result.writeByte(0xbf); + result.writeByte(0x02); + } else { + result.writeByte(b); + } + } + result.writeBytes(buf.readBytes(2)); + + return result; + } + + private static int checksum(byte[] data) + { + int sum = 0; + int len = data.length; + for (int j = 0; len > 1; len--) { + sum += data[j++] & 0xff; + if ((sum & 0x80000000) > 0) { + sum = (sum & 0xffff) + (sum >> 16); + } + } + if (len == 1) { + sum += data[data.length - 1] & 0xff; + } + while ((sum >> 16) > 0) { + sum = (sum & 0xffff) + sum >> 16; + } + sum = (sum == 0xffff) ? sum & 0xffff : (~sum) & 0xffff; + return sum; + } + + + private static ByteBuf encodeContent(String uniqueId, String content) { + ByteBuf buf = Unpooled.buffer(); + + byte[] message = content.getBytes(); + + buf.writeShort(0xFAAF); + buf.writeShort(0x0007); + buf.writeShort(0x0001); + buf.writeBytes(DataConverter.parseHex(uniqueId + "0"),0,8); + buf.writeShort(message.length); + buf.writeShort(checksum(message)); + buf.writeBytes(message); + buf.writeShort(0xFAAF); + + return encodeFrame(buf); + } + + @Override + protected Object encodeCommand(Command command) { + String uniqueId = getUniqueId(command.getDeviceId()); + + switch (command.getType()) { + case Command.TYPE_CUSTOM: + return encodeContent(uniqueId, command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_PERIODIC: + return encodeContent(uniqueId, String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); + case Command.TYPE_POWER_OFF: + return encodeContent(uniqueId, "of=1"); + case Command.TYPE_REBOOT_DEVICE: + return encodeContent(uniqueId, "reset"); + default: + return null; + } + } + +} diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java new file mode 100644 index 000000000..6d3b3e065 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java @@ -0,0 +1,29 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Command; + +public class Xexun2ProtocolEncoderTest extends ProtocolTest { + + @Test + public void testEncode() throws Exception { + + var encoder = inject(new Xexun2ProtocolEncoder(null)); + + Command command; + + command = new Command(); + command.setDeviceId(604080829351806311L); + command.setType(Command.TYPE_POWER_OFF); + verifyCommand(encoder, command, binary("FAAF0007000186220505123456700004FEBC6F663D31FAAF")); + + command = new Command(); + command.setDeviceId(604080829351806311L); + command.setType(Command.TYPE_POSITION_PERIODIC); + command.set(Command.KEY_FREQUENCY, 150); + verifyCommand(encoder, command, binary("FAAF0007000186220505123456700015F90E747261636B696E675F73656E643D3135302C313530FAAF")); + + } + +} -- cgit v1.2.3 From 8b63ce5c51fca9462e0e561b8ce07ae49afce6f8 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 13:34:02 +0000 Subject: Update Xexun2 Encoder --- src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java | 6 +++--- src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index d85c6734b..287364cf2 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -32,8 +32,8 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { } private static ByteBuf encodeFrame(ByteBuf buf) { - buf.clear(); - if (buf.readableBytes() < 5) { + int bufLength = buf.readableBytes(); + if (bufLength < 5) { return null; } @@ -41,7 +41,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { result.writeBytes(buf.readBytes(2)); - while (buf.readerIndex() < buf.capacity() - 2) { + while (buf.readerIndex() < bufLength - 2) { int b = buf.readUnsignedByte(); if (b == 0xfa && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xaf) { buf.readUnsignedByte(); diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java index 6d3b3e065..483bc85fa 100644 --- a/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java @@ -14,15 +14,15 @@ public class Xexun2ProtocolEncoderTest extends ProtocolTest { Command command; command = new Command(); - command.setDeviceId(604080829351806311L); + command.setDeviceId(1); command.setType(Command.TYPE_POWER_OFF); - verifyCommand(encoder, command, binary("FAAF0007000186220505123456700004FEBC6F663D31FAAF")); + verifyCommand(encoder, command, binary("FAAF0007000112345678901234500004FEBC6F663D31FAAF")); command = new Command(); - command.setDeviceId(604080829351806311L); + command.setDeviceId(1); command.setType(Command.TYPE_POSITION_PERIODIC); command.set(Command.KEY_FREQUENCY, 150); - verifyCommand(encoder, command, binary("FAAF0007000186220505123456700015F90E747261636B696E675F73656E643D3135302C313530FAAF")); + verifyCommand(encoder, command, binary("FAAF0007000112345678901234500015F90E747261636B696E675F73656E643D3135302C313530FAAF")); } -- cgit v1.2.3 From 1f0965d02081d0257a969927ba58de5b39e051bd Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 13:52:06 +0000 Subject: Update Xexun2 Decoder - do not ACK a command ACK --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 28e7fbda3..bdeb0fa78 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -42,6 +42,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { } public static final int MSG_POSITION = 0x14; + public static final int MSG_COMMAND = 0x07; private void sendResponse(Channel channel, int type, int index, ByteBuf imei) { if (channel != null) { @@ -99,12 +100,12 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } - sendResponse(channel, type, index, imei); - buf.readUnsignedShort(); // attributes buf.readUnsignedShort(); // checksum if (type == MSG_POSITION) { + sendResponse(channel, type, index, imei); + List lengths = new ArrayList<>(); List positions = new ArrayList<>(); -- cgit v1.2.3 From e91402cddad8763658572eb8e383fa8a16d69190 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 19:49:37 +0000 Subject: Update Xexun2 Encoder --- .../traccar/protocol/Xexun2ProtocolDecoder.java | 6 ++++-- .../traccar/protocol/Xexun2ProtocolEncoder.java | 24 +++++++++++----------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index bdeb0fa78..3c81ec27f 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -100,12 +100,14 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } + if (type != MSG_COMMAND) { + sendResponse(channel, type, index, imei); + } + buf.readUnsignedShort(); // attributes buf.readUnsignedShort(); // checksum if (type == MSG_POSITION) { - sendResponse(channel, type, index, imei); - List lengths = new ArrayList<>(); List positions = new ArrayList<>(); diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index 287364cf2..c31d6e747 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 Stefan Clark (stefan@stefanclark.co.uk) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,15 +22,15 @@ import org.traccar.helper.DataConverter; import org.traccar.model.Command; import org.traccar.Protocol; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; - public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { public Xexun2ProtocolEncoder(Protocol protocol) { super(protocol); } + public static final int FLAG = 0xfaaf; + public static final int MSG_COMMAND = 0x07; + private static ByteBuf encodeFrame(ByteBuf buf) { int bufLength = buf.readableBytes(); if (bufLength < 5) { @@ -62,8 +62,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { return result; } - private static int checksum(byte[] data) - { + private static int checksum(byte[] data) { int sum = 0; int len = data.length; for (int j = 0; len > 1; len--) { @@ -88,14 +87,14 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { byte[] message = content.getBytes(); - buf.writeShort(0xFAAF); - buf.writeShort(0x0007); - buf.writeShort(0x0001); - buf.writeBytes(DataConverter.parseHex(uniqueId + "0"),0,8); + buf.writeShort(FLAG); + buf.writeShort(MSG_COMMAND); + buf.writeShort(1); // index + buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); buf.writeShort(message.length); buf.writeShort(checksum(message)); buf.writeBytes(message); - buf.writeShort(0xFAAF); + buf.writeShort(FLAG); return encodeFrame(buf); } @@ -108,7 +107,8 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { case Command.TYPE_CUSTOM: return encodeContent(uniqueId, command.getString(Command.KEY_DATA)); case Command.TYPE_POSITION_PERIODIC: - return encodeContent(uniqueId, String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); + return encodeContent(uniqueId, + String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); case Command.TYPE_POWER_OFF: return encodeContent(uniqueId, "of=1"); case Command.TYPE_REBOOT_DEVICE: -- cgit v1.2.3 From f5033ce11b823a4fce080211368b8c6473d81e7b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 26 Jul 2022 16:59:58 -0700 Subject: Rename mail manager --- .../java/org/traccar/database/MailManager.java | 161 -------------------- .../java/org/traccar/mail/SmtpMailManager.java | 162 +++++++++++++++++++++ 2 files changed, 162 insertions(+), 161 deletions(-) delete mode 100644 src/main/java/org/traccar/database/MailManager.java create mode 100644 src/main/java/org/traccar/mail/SmtpMailManager.java diff --git a/src/main/java/org/traccar/database/MailManager.java b/src/main/java/org/traccar/database/MailManager.java deleted file mode 100644 index ec1681dcb..000000000 --- a/src/main/java/org/traccar/database/MailManager.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) - * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@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.database; - -import org.traccar.config.Config; -import org.traccar.config.ConfigKey; -import org.traccar.config.Keys; -import org.traccar.model.User; -import org.traccar.notification.PropertiesProvider; - -import javax.inject.Inject; -import javax.mail.BodyPart; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; -import java.io.UnsupportedEncodingException; -import java.util.Date; -import java.util.Properties; - -public final class MailManager { - - private static final String CONTENT_TYPE = "text/html; charset=utf-8"; - - private final Config config; - private final StatisticsManager statisticsManager; - - @Inject - public MailManager(Config config, StatisticsManager statisticsManager) { - this.config = config; - this.statisticsManager = statisticsManager; - } - - private static void copyBooleanProperty( - Properties properties, PropertiesProvider provider, ConfigKey key) { - Boolean value = provider.getBoolean(key); - if (value != null) { - properties.put(key.getKey(), String.valueOf(value)); - } - } - - private static void copyStringProperty( - Properties properties, PropertiesProvider provider, ConfigKey key) { - String value = provider.getString(key); - if (value != null) { - properties.put(key.getKey(), value); - } - } - - private static Properties getProperties(PropertiesProvider provider) { - String host = provider.getString(Keys.MAIL_SMTP_HOST); - if (host != null) { - Properties properties = new Properties(); - - properties.put(Keys.MAIL_TRANSPORT_PROTOCOL.getKey(), provider.getString(Keys.MAIL_TRANSPORT_PROTOCOL)); - properties.put(Keys.MAIL_SMTP_HOST.getKey(), host); - properties.put(Keys.MAIL_SMTP_PORT.getKey(), String.valueOf(provider.getInteger(Keys.MAIL_SMTP_PORT))); - - copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_ENABLE); - copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_REQUIRED); - copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_SSL_ENABLE); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_TRUST); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_PROTOCOLS); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_USERNAME); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_PASSWORD); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM); - copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM_NAME); - - return properties; - } - return null; - } - - public boolean getEmailEnabled() { - return config.hasKey(Keys.MAIL_SMTP_HOST); - } - - public void sendMessage( - User user, String subject, String body) throws MessagingException { - sendMessage(user, subject, body, null); - } - - public void sendMessage( - User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { - - Properties properties = null; - if (!config.getBoolean(Keys.MAIL_SMTP_IGNORE_USER_CONFIG)) { - properties = getProperties(new PropertiesProvider(user)); - } - if (properties == null) { - properties = getProperties(new PropertiesProvider(config)); - } - if (properties == null) { - throw new MessagingException("No SMTP configuration found"); - } - - Session session = Session.getInstance(properties); - - MimeMessage message = new MimeMessage(session); - - String from = properties.getProperty(Keys.MAIL_SMTP_FROM.getKey()); - if (from != null) { - String fromName = properties.getProperty(Keys.MAIL_SMTP_FROM_NAME.getKey()); - if (fromName != null) { - try { - message.setFrom(new InternetAddress(from, fromName)); - } catch (UnsupportedEncodingException e) { - throw new MessagingException("Email address issue"); - } - } else { - message.setFrom(new InternetAddress(from)); - } - } - - message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); - message.setSubject(subject); - message.setSentDate(new Date()); - - if (attachment != null) { - Multipart multipart = new MimeMultipart(); - - BodyPart messageBodyPart = new MimeBodyPart(); - messageBodyPart.setContent(body, CONTENT_TYPE); - multipart.addBodyPart(messageBodyPart); - multipart.addBodyPart(attachment); - - message.setContent(multipart); - } else { - message.setContent(body, CONTENT_TYPE); - } - - try (Transport transport = session.getTransport()) { - statisticsManager.registerMail(); - transport.connect( - properties.getProperty(Keys.MAIL_SMTP_HOST.getKey()), - properties.getProperty(Keys.MAIL_SMTP_USERNAME.getKey()), - properties.getProperty(Keys.MAIL_SMTP_PASSWORD.getKey())); - transport.sendMessage(message, message.getAllRecipients()); - } - } - -} diff --git a/src/main/java/org/traccar/mail/SmtpMailManager.java b/src/main/java/org/traccar/mail/SmtpMailManager.java new file mode 100644 index 000000000..7763c86cc --- /dev/null +++ b/src/main/java/org/traccar/mail/SmtpMailManager.java @@ -0,0 +1,162 @@ +/* + * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 Andrey Kunitsyn (andrey@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.mail; + +import org.traccar.config.Config; +import org.traccar.config.ConfigKey; +import org.traccar.config.Keys; +import org.traccar.database.StatisticsManager; +import org.traccar.model.User; +import org.traccar.notification.PropertiesProvider; + +import javax.inject.Inject; +import javax.mail.BodyPart; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.util.Properties; + +public final class SmtpMailManager implements MailManager { + + private static final String CONTENT_TYPE = "text/html; charset=utf-8"; + + private final Config config; + private final StatisticsManager statisticsManager; + + @Inject + public SmtpMailManager(Config config, StatisticsManager statisticsManager) { + this.config = config; + this.statisticsManager = statisticsManager; + } + + private static void copyBooleanProperty( + Properties properties, PropertiesProvider provider, ConfigKey key) { + Boolean value = provider.getBoolean(key); + if (value != null) { + properties.put(key.getKey(), String.valueOf(value)); + } + } + + private static void copyStringProperty( + Properties properties, PropertiesProvider provider, ConfigKey key) { + String value = provider.getString(key); + if (value != null) { + properties.put(key.getKey(), value); + } + } + + private static Properties getProperties(PropertiesProvider provider) { + String host = provider.getString(Keys.MAIL_SMTP_HOST); + if (host != null) { + Properties properties = new Properties(); + + properties.put(Keys.MAIL_TRANSPORT_PROTOCOL.getKey(), provider.getString(Keys.MAIL_TRANSPORT_PROTOCOL)); + properties.put(Keys.MAIL_SMTP_HOST.getKey(), host); + properties.put(Keys.MAIL_SMTP_PORT.getKey(), String.valueOf(provider.getInteger(Keys.MAIL_SMTP_PORT))); + + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_ENABLE); + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_STARTTLS_REQUIRED); + copyBooleanProperty(properties, provider, Keys.MAIL_SMTP_SSL_ENABLE); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_TRUST); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_SSL_PROTOCOLS); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_USERNAME); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_PASSWORD); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM); + copyStringProperty(properties, provider, Keys.MAIL_SMTP_FROM_NAME); + + return properties; + } + return null; + } + + public boolean getEmailEnabled() { + return config.hasKey(Keys.MAIL_SMTP_HOST); + } + + public void sendMessage( + User user, String subject, String body) throws MessagingException { + sendMessage(user, subject, body, null); + } + + public void sendMessage( + User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { + + Properties properties = null; + if (!config.getBoolean(Keys.MAIL_SMTP_IGNORE_USER_CONFIG)) { + properties = getProperties(new PropertiesProvider(user)); + } + if (properties == null) { + properties = getProperties(new PropertiesProvider(config)); + } + if (properties == null) { + throw new MessagingException("No SMTP configuration found"); + } + + Session session = Session.getInstance(properties); + + MimeMessage message = new MimeMessage(session); + + String from = properties.getProperty(Keys.MAIL_SMTP_FROM.getKey()); + if (from != null) { + String fromName = properties.getProperty(Keys.MAIL_SMTP_FROM_NAME.getKey()); + if (fromName != null) { + try { + message.setFrom(new InternetAddress(from, fromName)); + } catch (UnsupportedEncodingException e) { + throw new MessagingException("Email address issue"); + } + } else { + message.setFrom(new InternetAddress(from)); + } + } + + message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); + message.setSubject(subject); + message.setSentDate(new Date()); + + if (attachment != null) { + Multipart multipart = new MimeMultipart(); + + BodyPart messageBodyPart = new MimeBodyPart(); + messageBodyPart.setContent(body, CONTENT_TYPE); + multipart.addBodyPart(messageBodyPart); + multipart.addBodyPart(attachment); + + message.setContent(multipart); + } else { + message.setContent(body, CONTENT_TYPE); + } + + try (Transport transport = session.getTransport()) { + statisticsManager.registerMail(); + transport.connect( + properties.getProperty(Keys.MAIL_SMTP_HOST.getKey()), + properties.getProperty(Keys.MAIL_SMTP_USERNAME.getKey()), + properties.getProperty(Keys.MAIL_SMTP_PASSWORD.getKey())); + transport.sendMessage(message, message.getAllRecipients()); + } + } + +} -- cgit v1.2.3 From 8f129e2a70abbea66f33213c84b7e63f9e96035a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 26 Jul 2022 17:12:51 -0700 Subject: Testing mail manager --- debug.xml | 2 + src/main/java/org/traccar/MainModule.java | 12 ++++++ .../org/traccar/api/resource/PasswordResource.java | 2 +- .../org/traccar/api/resource/ReportResource.java | 2 +- .../org/traccar/api/resource/ServerResource.java | 2 +- src/main/java/org/traccar/config/Keys.java | 7 ++++ src/main/java/org/traccar/mail/LogMailManager.java | 44 ++++++++++++++++++++++ src/main/java/org/traccar/mail/MailManager.java | 31 +++++++++++++++ .../java/org/traccar/mail/SmtpMailManager.java | 2 - .../org/traccar/notificators/NotificatorMail.java | 2 +- 10 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/traccar/mail/LogMailManager.java create mode 100644 src/main/java/org/traccar/mail/MailManager.java diff --git a/debug.xml b/debug.xml index a597d83c5..b38b4f9ac 100644 --- a/debug.xml +++ b/debug.xml @@ -16,6 +16,8 @@ true true + true + org.h2.Driver jdbc:h2:./target/database sa diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index b9543af25..b8ff21472 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -63,6 +63,9 @@ import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; import org.traccar.helper.SanitizerModule; +import org.traccar.mail.LogMailManager; +import org.traccar.mail.MailManager; +import org.traccar.mail.SmtpMailManager; import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; @@ -128,6 +131,15 @@ public class MainModule extends AbstractModule { return null; } + @Provides + public static MailManager provideMailManager(Config config, StatisticsManager statisticsManager) { + if (config.getBoolean(Keys.MAIL_DEBUG)) { + return new LogMailManager(); + } else { + return new SmtpMailManager(config, statisticsManager); + } + } + @Singleton @Provides public static LdapProvider provideLdapProvider(Config config) { diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 643471797..88906e7e6 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -16,7 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; -import org.traccar.database.MailManager; +import org.traccar.mail.MailManager; import org.traccar.model.User; import org.traccar.notification.TextTemplateFormatter; import org.traccar.storage.StorageException; diff --git a/src/main/java/org/traccar/api/resource/ReportResource.java b/src/main/java/org/traccar/api/resource/ReportResource.java index 6176013c1..70177dd4d 100644 --- a/src/main/java/org/traccar/api/resource/ReportResource.java +++ b/src/main/java/org/traccar/api/resource/ReportResource.java @@ -19,7 +19,7 @@ package org.traccar.api.resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.api.BaseResource; -import org.traccar.database.MailManager; +import org.traccar.mail.MailManager; import org.traccar.helper.LogAction; import org.traccar.model.Event; import org.traccar.model.Position; diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index 4fc76a0d7..e35cd7d95 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -16,7 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; -import org.traccar.database.MailManager; +import org.traccar.mail.MailManager; import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; import org.traccar.helper.LogAction; diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 2190f82f7..e97e104a1 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -800,6 +800,13 @@ public final class Keys { List.of(KeyType.CONFIG), "templates"); + /** + * Log emails instead of sending them via SMTP. Intended for testing purposes only. + */ + public static final ConfigKey MAIL_DEBUG = new BooleanConfigKey( + "mail.debug", + List.of(KeyType.CONFIG)); + /** * Force SMTP settings from the config file and ignore user attributes. */ diff --git a/src/main/java/org/traccar/mail/LogMailManager.java b/src/main/java/org/traccar/mail/LogMailManager.java new file mode 100644 index 000000000..b6b912d6c --- /dev/null +++ b/src/main/java/org/traccar/mail/LogMailManager.java @@ -0,0 +1,44 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.mail; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.model.User; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; + +public class LogMailManager implements MailManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(LogMailManager.class); + + @Override + public boolean getEmailEnabled() { + return true; + } + + @Override + public void sendMessage(User user, String subject, String body) throws MessagingException { + sendMessage(user, subject, body, null); + } + + @Override + public void sendMessage(User user, String subject, String body, MimeBodyPart attachment) throws MessagingException { + LOGGER.info("\nTo: " + user.getEmail() + "\nSubject: " + subject + "\nBody:\n" + body); + } + +} diff --git a/src/main/java/org/traccar/mail/MailManager.java b/src/main/java/org/traccar/mail/MailManager.java new file mode 100644 index 000000000..69efbed32 --- /dev/null +++ b/src/main/java/org/traccar/mail/MailManager.java @@ -0,0 +1,31 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.mail; + +import org.traccar.model.User; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; + +public interface MailManager { + + boolean getEmailEnabled(); + + void sendMessage(User user, String subject, String body) throws MessagingException; + + void sendMessage(User user, String subject, String body, MimeBodyPart attachment) throws MessagingException; + +} diff --git a/src/main/java/org/traccar/mail/SmtpMailManager.java b/src/main/java/org/traccar/mail/SmtpMailManager.java index 7763c86cc..4a0b7048f 100644 --- a/src/main/java/org/traccar/mail/SmtpMailManager.java +++ b/src/main/java/org/traccar/mail/SmtpMailManager.java @@ -23,7 +23,6 @@ import org.traccar.database.StatisticsManager; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; -import javax.inject.Inject; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.MessagingException; @@ -45,7 +44,6 @@ public final class SmtpMailManager implements MailManager { private final Config config; private final StatisticsManager statisticsManager; - @Inject public SmtpMailManager(Config config, StatisticsManager statisticsManager) { this.config = config; this.statisticsManager = statisticsManager; diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 647832166..75571cfc4 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -16,7 +16,7 @@ */ package org.traccar.notificators; -import org.traccar.database.MailManager; +import org.traccar.mail.MailManager; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; -- cgit v1.2.3 From 535eb8d11fccfa7ba4bfcbe9e3d8a0bc9be8f247 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 26 Jul 2022 17:17:24 -0700 Subject: Fix password reset --- src/main/java/org/traccar/api/resource/PasswordResource.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 88906e7e6..91c2d8ecf 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -58,7 +58,8 @@ public class PasswordResource extends BaseResource { if (user != null) { String token = UUID.randomUUID().toString().replaceAll("-", ""); user.set(PASSWORD_RESET_TOKEN, token); - storage.updateObject(user, new Request(new Columns.Exclude("id"), new Condition.Equals("id", "id"))); + storage.updateObject(user, new Request( + new Columns.Include("attributes"), new Condition.Equals("id", "id"))); var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); velocityContext.put("token", token); @@ -79,7 +80,8 @@ public class PasswordResource extends BaseResource { if (user != null) { user.getAttributes().remove(PASSWORD_RESET_TOKEN); user.setPassword(password); - storage.updateObject(user, new Request(new Columns.Exclude("id"), new Condition.Equals("id", "id"))); + storage.updateObject(user, new Request( + new Columns.Include("attributes", "hashedPassword", "salt"), new Condition.Equals("id", "id"))); return Response.ok().build(); } return Response.status(Response.Status.NOT_FOUND).build(); -- cgit v1.2.3 From c5f793815a6429d77c429f49c876f52062051f03 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 26 Jul 2022 17:29:14 -0700 Subject: Handle connectionless protocols --- src/main/java/org/traccar/MainEventHandler.java | 7 +++---- src/main/java/org/traccar/session/ConnectionManager.java | 6 ++++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 981888577..52eb43faf 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -159,10 +159,9 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { LOGGER.info("[{}] disconnected", NetworkUtil.session(ctx.channel())); closeChannel(ctx.channel()); - if (BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null - && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName())) { - connectionManager.deviceDisconnected(ctx.channel()); - } + boolean supportsOffline = BasePipelineFactory.getHandler(ctx.pipeline(), HttpRequestDecoder.class) == null + && !connectionlessProtocols.contains(ctx.pipeline().get(BaseProtocolDecoder.class).getProtocolName()); + connectionManager.deviceDisconnected(ctx.channel(), supportsOffline); } @Override diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 2d183ee22..262a302af 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -189,12 +189,14 @@ public class ConnectionManager implements BroadcastInterface { } } - public void deviceDisconnected(Channel channel) { + public void deviceDisconnected(Channel channel, boolean supportsOffline) { Endpoint endpoint = new Endpoint(channel, channel.remoteAddress()); Map endpointSessions = sessionsByEndpoint.remove(endpoint); if (endpointSessions != null) { for (DeviceSession deviceSession : endpointSessions.values()) { - updateDevice(deviceSession.getDeviceId(), Device.STATUS_OFFLINE, null); + if (supportsOffline) { + updateDevice(deviceSession.getDeviceId(), Device.STATUS_OFFLINE, null); + } sessionsByDeviceId.remove(deviceSession.getDeviceId()); cacheManager.removeDevice(deviceSession.getDeviceId()); } -- cgit v1.2.3 From de2219565e4a61aa0d64b03650ec36ef6d17de93 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Wed, 27 Jul 2022 15:47:18 +0100 Subject: Update Xexun2 Encoder --- .../java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 9 +++------ .../java/org/traccar/protocol/Xexun2ProtocolEncoder.java | 15 ++++++++------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 3c81ec27f..8deb2328b 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -42,13 +42,11 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { } public static final int MSG_POSITION = 0x14; - public static final int MSG_COMMAND = 0x07; private void sendResponse(Channel channel, int type, int index, ByteBuf imei) { if (channel != null) { ByteBuf response = Unpooled.buffer(); - response.writeByte(0xfa); - response.writeByte(0xaf); + response.writeShort(Xexun2ProtocolEncoder.FLAG); response.writeShort(type); response.writeShort(index); @@ -57,8 +55,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { response.writeShort(0xfffe); // checksum response.writeByte(1); // response - response.writeByte(0xfa); - response.writeByte(0xaf); + response.writeShort(Xexun2ProtocolEncoder.FLAG); channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } @@ -100,7 +97,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } - if (type != MSG_COMMAND) { + if (type != Xexun2ProtocolEncoder.MSG_COMMAND) { sendResponse(channel, type, index, imei); } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index c31d6e747..f876853bf 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -62,17 +62,17 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { return result; } - private static int checksum(byte[] data) { + private static int udpchecksum(ByteBuf data) { int sum = 0; - int len = data.length; + int len = data.capacity(); for (int j = 0; len > 1; len--) { - sum += data[j++] & 0xff; + sum += data.readByte() & 0xff; if ((sum & 0x80000000) > 0) { sum = (sum & 0xffff) + (sum >> 16); } } if (len == 1) { - sum += data[data.length - 1] & 0xff; + sum += data.readByte() & 0xff; } while ((sum >> 16) > 0) { sum = (sum & 0xffff) + sum >> 16; @@ -85,14 +85,15 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { private static ByteBuf encodeContent(String uniqueId, String content) { ByteBuf buf = Unpooled.buffer(); - byte[] message = content.getBytes(); + ByteBuf message = Unpooled.copiedBuffer(content.getBytes()); buf.writeShort(FLAG); buf.writeShort(MSG_COMMAND); buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); - buf.writeShort(message.length); - buf.writeShort(checksum(message)); + buf.writeShort(message.capacity()); + buf.writeShort(udpchecksum(message)); + message.resetReaderIndex(); buf.writeBytes(message); buf.writeShort(FLAG); -- cgit v1.2.3 From 42e88c2bf95962f1274a8bbb6e8fc09af95f627f Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Thu, 28 Jul 2022 22:37:15 +0100 Subject: Added udp() to Checksum helper and Updated Xexun2 procotol --- src/main/java/org/traccar/helper/Checksum.java | 19 +++++++++++++++++ .../traccar/protocol/Xexun2ProtocolDecoder.java | 11 +++++++--- .../traccar/protocol/Xexun2ProtocolEncoder.java | 24 ++-------------------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/traccar/helper/Checksum.java b/src/main/java/org/traccar/helper/Checksum.java index 8c3d0063a..e660790ef 100644 --- a/src/main/java/org/traccar/helper/Checksum.java +++ b/src/main/java/org/traccar/helper/Checksum.java @@ -200,4 +200,23 @@ public final class Checksum { return (10 - (checksum % 10)) % 10; } + public static int udp(ByteBuffer data) { + int sum = 0; + int len = data.capacity(); + for (int j = 0; len > 1; len--) { + sum += data.get() & 0xff; + if ((sum & 0x80000000) > 0) { + sum = (sum & 0xffff) + (sum >> 16); + } + } + if (len == 1) { + sum += data.get() & 0xff; + } + while ((sum >> 16) > 0) { + sum = (sum & 0xffff) + sum >> 16; + } + sum = (sum == 0xffff) ? sum & 0xffff : (~sum) & 0xffff; + return sum; + } + } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 8deb2328b..f0158e6ce 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -24,6 +24,7 @@ import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -97,13 +98,17 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } + int payloadSize = buf.readUnsignedShort() & 0x03ff; + int checksum = buf.readUnsignedShort(); // checksum + + if (checksum != Checksum.udp(buf.nioBuffer(buf.readerIndex(), payloadSize))) { + return null; + } + if (type != Xexun2ProtocolEncoder.MSG_COMMAND) { sendResponse(channel, type, index, imei); } - buf.readUnsignedShort(); // attributes - buf.readUnsignedShort(); // checksum - if (type == MSG_POSITION) { List lengths = new ArrayList<>(); List positions = new ArrayList<>(); diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index f876853bf..6e1e1d68d 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; import org.traccar.model.Command; import org.traccar.Protocol; @@ -62,26 +63,6 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { return result; } - private static int udpchecksum(ByteBuf data) { - int sum = 0; - int len = data.capacity(); - for (int j = 0; len > 1; len--) { - sum += data.readByte() & 0xff; - if ((sum & 0x80000000) > 0) { - sum = (sum & 0xffff) + (sum >> 16); - } - } - if (len == 1) { - sum += data.readByte() & 0xff; - } - while ((sum >> 16) > 0) { - sum = (sum & 0xffff) + sum >> 16; - } - sum = (sum == 0xffff) ? sum & 0xffff : (~sum) & 0xffff; - return sum; - } - - private static ByteBuf encodeContent(String uniqueId, String content) { ByteBuf buf = Unpooled.buffer(); @@ -92,8 +73,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); buf.writeShort(message.capacity()); - buf.writeShort(udpchecksum(message)); - message.resetReaderIndex(); + buf.writeShort(Checksum.udp(message.nioBuffer())); buf.writeBytes(message); buf.writeShort(FLAG); -- cgit v1.2.3 From fd221e21f21e04132742e34056db696b6156e5a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 07:10:53 -0700 Subject: Disable sanitization by default --- debug.xml | 1 - setup/default.xml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/debug.xml b/debug.xml index b38b4f9ac..e02c1b15d 100644 --- a/debug.xml +++ b/debug.xml @@ -7,7 +7,6 @@ ./setup/default.xml ./traccar-web/web - false true true diff --git a/setup/default.xml b/setup/default.xml index dea638d7a..62494f814 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -12,7 +12,7 @@ 8082 ./web - true + false false true -- cgit v1.2.3 From 346441e52256bca70b88dc6adad6bd3aa97da2a1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 07:16:27 -0700 Subject: Split web paths --- setup/default.xml | 2 +- setup/package.sh | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index 62494f814..0abc96431 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -11,7 +11,7 @@ --> 8082 - ./web + ./modern false false diff --git a/setup/package.sh b/setup/package.sh index e5f976b79..40dac475d 100755 --- a/setup/package.sh +++ b/setup/package.sh @@ -81,13 +81,14 @@ else fi prepare () { - mkdir -p out/{conf,data,lib,logs,web,schema,templates} + mkdir -p out/{conf,data,lib,logs,legacy,modern,schema,templates} cp ../target/tracker-server.jar out cp ../target/lib/* out/lib cp ../schema/* out/schema cp -r ../templates/* out/templates - cp -r ../traccar-web/web/* out/web + cp -r ../traccar-web/web/* out/legacy + cp -r ../traccar-web/modern/build/* out/modern cp default.xml out/conf cp traccar.xml out/conf -- cgit v1.2.3 From f028f926ad1c59268c591d1f095f0f77e36a814a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 07:20:01 -0700 Subject: Better missing file handing --- src/main/java/org/traccar/web/WebServer.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 68eee78e7..704a4b3cd 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -64,6 +64,7 @@ import java.io.IOException; import java.io.Writer; import java.net.InetSocketAddress; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.EnumSet; @@ -104,9 +105,9 @@ public class WebServer implements LifecycleObject { @Override protected void handleErrorPage( HttpServletRequest request, Writer writer, int code, String message) throws IOException { - if (code == HttpStatus.NOT_FOUND_404 && request.getPathInfo().startsWith("/modern")) { - writer.write(Files.readString( - Paths.get(config.getString(Keys.WEB_PATH), "modern", "index.html"))); + Path index = Paths.get(config.getString(Keys.WEB_PATH), "index.html"); + if (code == HttpStatus.NOT_FOUND_404 && Files.exists(index)) { + writer.write(Files.readString(index)); } else { writer.write("Error" + code + " - " + HttpStatus.getMessage(code) + ""); -- cgit v1.2.3 From ccaa4d13d81901d7001d32795c36b9be53d4c244 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 07:27:15 -0700 Subject: Other modern cleanup --- templates/full/passwordReset.vm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/full/passwordReset.vm b/templates/full/passwordReset.vm index 38da10aa3..d380790dc 100644 --- a/templates/full/passwordReset.vm +++ b/templates/full/passwordReset.vm @@ -3,6 +3,6 @@ To reset password please click on the following link:
-$webUrl/modern/reset-password?passwordReset=$token
+$webUrl/reset-password?passwordReset=$token
-- cgit v1.2.3 From 80e8844a6b0932e13bda84908adc48f8a2cb93ac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 07:53:21 -0700 Subject: Update Java versions --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index beeafe58f..a11ad2640 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,9 +46,9 @@ jobs: working-directory: ./setup run: | wget -q http://files.jrsoftware.org/is/5/isetup-5.5.6.exe - wget -q https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-11.0.13.8-1/java-11-openjdk-11.0.13.8-1.windows.ojdkbuild.x86_64.zip - wget -q https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-x64.zip - wget -q https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.13%2B8/jdk-11.0.13-ojdkbuild-linux-armhf.zip + wget -q https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-11.0.15.9-1/java-11-openjdk-11.0.15.9-1.windows.ojdkbuild.x86_64.zip + wget -q https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.15%2B10/jdk-11.0.15-ojdkbuild-linux-x64.zip + wget -q https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.15%2B10/jdk-11.0.15-ojdkbuild-linux-armhf.zip ./package.sh ${{ github.event.inputs.version }} - name: Upload installers working-directory: ./setup -- cgit v1.2.3 From f4c0264df170719d645f0cc57b609f1a2d786249 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 08:29:04 -0700 Subject: Try different java distribution --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a11ad2640..655d47b80 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: working-directory: ./traccar-web - uses: actions/setup-java@v3 with: - distribution: zulu + distribution: temurin java-version: 11 cache: gradle - run: ./gradlew build -- cgit v1.2.3 From 91584d16eb8585d302d52b76058b7cc5c6b74d4f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 10:13:28 -0700 Subject: Minor Teltonika refactoring --- .../java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 77047fe26..a7c46402f 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -197,13 +197,13 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeOtherParameter(Position position, int id, ByteBuf buf, int length) { + private void decodeUniversalParameter(Position position, int id, ByteBuf buf, int length) { switch (id) { case 1: case 2: case 3: case 4: - position.set("di" + id, readValue(buf, length, false)); + position.set(Position.PREFIX_IN + id, readValue(buf, length, false)); break; case 9: position.set(Position.PREFIX_ADC + 1, readValue(buf, length, false)); @@ -355,7 +355,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_GH3000) { decodeGh3000Parameter(position, id, buf, length); } else { - decodeOtherParameter(position, id, buf, length); + decodeUniversalParameter(position, id, buf, length); } } @@ -508,7 +508,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_8 || codec == CODEC_8_EXT || codec == CODEC_16) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeOtherParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8, codec); } } -- cgit v1.2.3 From 54bcbdc6ed9aec8fe5bdfa76dfc7698f7504df84 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 11:25:52 -0700 Subject: Rename variable --- src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 88b7d12c8..8a58ebc5e 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -204,11 +204,11 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + i, parser.nextHexInt()); } - String deviceModel = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); - if (deviceModel == null) { - deviceModel = ""; + String model = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); + if (model == null) { + model = ""; } - switch (deviceModel.toUpperCase()) { + switch (model.toUpperCase()) { case "MVT340": case "MVT380": position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.0 * 2.0 / 1024.0); -- cgit v1.2.3 From 2d0d2cd39b40a1b62435efaa193bcf4680f109db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 31 Jul 2022 11:26:23 -0700 Subject: Better Teltonika support (fix #3988) --- .../traccar/protocol/TeltonikaProtocolDecoder.java | 254 ++++++++++----------- 1 file changed, 117 insertions(+), 137 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index a7c46402f..2b1196d55 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.model.Device; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -38,11 +39,15 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { private static final int IMAGE_PACKET_MAX = 2048; + private static final Map, BiConsumer>> PARAMETERS = new HashMap<>(); + private final boolean connectionless; private boolean extended; private final Map photos = new HashMap<>(); @@ -184,185 +189,160 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private long readValue(ByteBuf buf, int length, boolean signed) { + private long readValue(ByteBuf buf, int length) { switch (length) { case 1: - return signed ? buf.readByte() : buf.readUnsignedByte(); + return buf.readUnsignedByte(); case 2: - return signed ? buf.readShort() : buf.readUnsignedShort(); + return buf.readUnsignedShort(); case 4: - return signed ? buf.readInt() : buf.readUnsignedInt(); + return buf.readUnsignedInt(); default: return buf.readLong(); } } - private void decodeUniversalParameter(Position position, int id, ByteBuf buf, int length) { - switch (id) { - case 1: - case 2: - case 3: - case 4: - position.set(Position.PREFIX_IN + id, readValue(buf, length, false)); - break; - case 9: - position.set(Position.PREFIX_ADC + 1, readValue(buf, length, false)); - break; - case 10: - position.set(Position.PREFIX_ADC + 2, readValue(buf, length, false)); - break; - case 16: - position.set(Position.KEY_ODOMETER, readValue(buf, length, false)); - break; - case 17: - position.set("axisX", readValue(buf, length, true)); - break; - case 18: - position.set("axisY", readValue(buf, length, true)); - break; - case 19: - position.set("axisZ", readValue(buf, length, true)); - break; - case 21: - position.set(Position.KEY_RSSI, readValue(buf, length, false)); - break; - case 25: - case 26: - case 27: - case 28: - position.set(Position.PREFIX_TEMP + (id - 24 + 4), readValue(buf, length, true) * 0.1); - break; - case 66: - position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); - break; - case 67: - position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); - break; - case 72: - case 73: - case 74: - position.set(Position.PREFIX_TEMP + (id - 71), readValue(buf, length, true) * 0.1); - break; - case 78: - long driverUniqueId = readValue(buf, length, false); - if (driverUniqueId != 0) { - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId)); - } - break; - case 80: - position.set("workMode", readValue(buf, length, false)); - break; - case 90: - position.set(Position.KEY_DOOR, readValue(buf, length, false)); - break; - case 115: - position.set(Position.KEY_COOLANT_TEMP, readValue(buf, length, true) * 0.1); - break; - case 179: - position.set(Position.PREFIX_OUT + 1, readValue(buf, length, false) == 1); - break; - case 180: - position.set(Position.PREFIX_OUT + 2, readValue(buf, length, false) == 1); - break; - case 181: - position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); - break; - case 182: - position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); - break; - case 199: - position.set(Position.KEY_ODOMETER_TRIP, readValue(buf, length, false)); - break; - case 236: - if (readValue(buf, length, false) == 1) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - break; - case 239: - position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); - break; - case 240: - position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); - break; - case 241: - position.set(Position.KEY_OPERATOR, readValue(buf, length, false)); - break; - case 253: - switch ((int) readValue(buf, length, false)) { - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - default: - break; - } - break; - default: - position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); - break; - } + private static void register(int id, Set models, BiConsumer handler) { + PARAMETERS.computeIfAbsent(id, key -> new HashMap<>()).put(models, handler); + } + + static { + var fmbXXX = Set.of( + "FMB001", "FMB010", "FMB002", "FMB020", "FMB003", "FMB110", "FMB120", "FMB122", "FMB125", "FMB130", + "FMB140", "FMU125", "FMB900", "FMB920", "FMB962", "FMB964", "FM3001", "FMB202", "FMB204", "FMB206", + "FMT100", "MTB100", "FMP100", "MSP500"); + + register(1, null, (p, b) -> p.set(Position.PREFIX_IN + 1, b.readUnsignedByte() > 0)); + register(2, null, (p, b) -> p.set(Position.PREFIX_IN + 2, b.readUnsignedByte() > 0)); + register(3, null, (p, b) -> p.set(Position.PREFIX_IN + 3, b.readUnsignedByte() > 0)); + register(4, null, (p, b) -> p.set(Position.PREFIX_IN + 4, b.readUnsignedByte() > 0)); + register(9, fmbXXX, (p, b) -> p.set(Position.PREFIX_ADC + 1, b.readUnsignedShort() * 0.001)); + register(10, fmbXXX, (p, b) -> p.set(Position.PREFIX_ADC + 2, b.readUnsignedShort() * 0.001)); + register(11, fmbXXX, (p, b) -> p.set(Position.KEY_ICCID, String.valueOf(b.readLong()))); + register(12, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_USED, b.readUnsignedInt() * 0.001)); + register(13, fmbXXX, (p, b) -> p.set(Position.KEY_FUEL_CONSUMPTION, b.readUnsignedShort() * 0.01)); + register(16, null, (p, b) -> p.set(Position.KEY_ODOMETER, b.readUnsignedInt())); + register(17, null, (p, b) -> p.set("axisX", b.readShort())); + register(18, null, (p, b) -> p.set("axisY", b.readShort())); + register(19, null, (p, b) -> p.set("axisZ", b.readShort())); + register(21, null, (p, b) -> p.set(Position.KEY_RSSI, b.readUnsignedByte())); + register(24, fmbXXX, (p, b) -> p.setSpeed(UnitsConverter.knotsFromKph(b.readUnsignedShort()))); + register(25, null, (p, b) -> p.set("bleTemp1", b.readShort() * 0.01)); + register(26, null, (p, b) -> p.set("bleTemp2", b.readShort() * 0.01)); + register(27, null, (p, b) -> p.set("bleTemp3", b.readShort() * 0.01)); + register(28, null, (p, b) -> p.set("bleTemp4", b.readShort() * 0.01)); + register(66, null, (p, b) -> p.set(Position.KEY_POWER, b.readUnsignedShort() * 0.001)); + register(67, null, (p, b) -> p.set(Position.KEY_BATTERY, b.readUnsignedShort() * 0.001)); + register(68, fmbXXX, (p, b) -> p.set("batteryCurrent", b.readUnsignedShort() * 0.001)); + register(72, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 1, b.readShort() * 0.1)); + register(73, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 2, b.readShort() * 0.1)); + register(74, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 3, b.readShort() * 0.1)); + register(75, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 4, b.readShort() * 0.1)); + register(78, null, (p, b) -> { + long driverUniqueId = b.readLong(); + if (driverUniqueId > 0) { + p.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId)); + } + }); + register(80, null, (p, b) -> p.set("dataMode", b.readUnsignedByte())); + register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); + register(115, fmbXXX, (p, b) -> p.set(Position.KEY_COOLANT_TEMP, b.readShort() * 0.1)); + register(179, null, (p, b) -> p.set(Position.PREFIX_OUT + 1, b.readUnsignedByte() > 0)); + register(180, null, (p, b) -> p.set(Position.PREFIX_OUT + 2, b.readUnsignedByte() > 0)); + register(181, null, (p, b) -> p.set(Position.KEY_PDOP, b.readUnsignedShort() * 0.1)); + register(182, null, (p, b) -> p.set(Position.KEY_HDOP, b.readUnsignedShort() * 0.1)); + register(199, null, (p, b) -> p.set(Position.KEY_ODOMETER_TRIP, b.readUnsignedInt())); + register(200, fmbXXX, (p, b) -> p.set("sleepMode", b.readUnsignedByte())); + register(205, null, (p, b) -> p.set("cid", b.readUnsignedShort())); + register(206, null, (p, b) -> p.set("lac", b.readUnsignedShort())); + register(236, null, (p, b) -> { + p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_GENERAL : null); + }); + register(239, null, (p, b) -> p.set(Position.KEY_IGNITION, b.readUnsignedByte() > 0)); + register(240, null, (p, b) -> p.set(Position.KEY_MOTION, b.readUnsignedByte() > 0)); + register(241, null, (p, b) -> p.set(Position.KEY_OPERATOR, b.readUnsignedInt())); + register(253, null, (p, b) -> { + switch (b.readUnsignedByte()) { + case 1: + p.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 2: + p.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 3: + p.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + default: + break; + } + }); } private void decodeGh3000Parameter(Position position, int id, ByteBuf buf, int length) { switch (id) { case 1: - position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length, false)); + position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length)); break; case 2: - position.set("usbConnected", readValue(buf, length, false) == 1); + position.set("usbConnected", readValue(buf, length) == 1); break; case 5: - position.set("uptime", readValue(buf, length, false)); + position.set("uptime", readValue(buf, length)); break; case 20: - position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); + position.set(Position.KEY_HDOP, readValue(buf, length) * 0.1); break; case 21: - position.set(Position.KEY_VDOP, readValue(buf, length, false) * 0.1); + position.set(Position.KEY_VDOP, readValue(buf, length) * 0.1); break; case 22: - position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); + position.set(Position.KEY_PDOP, readValue(buf, length) * 0.1); break; case 67: - position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); + position.set(Position.KEY_BATTERY, readValue(buf, length) * 0.001); break; case 221: - position.set("button", readValue(buf, length, false)); + position.set("button", readValue(buf, length)); break; case 222: - if (readValue(buf, length, false) == 1) { + if (readValue(buf, length) == 1) { position.set(Position.KEY_ALARM, Position.ALARM_SOS); } break; case 240: - position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); + position.set(Position.KEY_MOTION, readValue(buf, length) == 1); break; case 244: - position.set(Position.KEY_ROAMING, readValue(buf, length, false) == 1); + position.set(Position.KEY_ROAMING, readValue(buf, length) == 1); break; default: - position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); + position.set(Position.PREFIX_IO + id, readValue(buf, length)); break; } } - private void decodeParameter(Position position, int id, ByteBuf buf, int length, int codec) { + private void decodeParameter(Position position, int id, ByteBuf buf, int length, int codec, String model) { if (codec == CODEC_GH3000) { decodeGh3000Parameter(position, id, buf, length); } else { - decodeUniversalParameter(position, id, buf, length); + boolean decoded = false; + for (var entry : PARAMETERS.getOrDefault(id, new HashMap<>()).entrySet()) { + if (entry.getKey() == null || model != null && entry.getKey().contains(model)) { + entry.getValue().accept(position, buf); + decoded = true; + break; + } + } + if (!decoded) { + position.set(Position.PREFIX_IO + id, readValue(buf, length)); + } } } private void decodeNetwork(Position position) { - long cid = position.getLong(Position.PREFIX_IO + 205); - int lac = position.getInteger(Position.PREFIX_IO + 206); - if (cid != 0 && lac != 0) { + Integer cid = (Integer) position.getAttributes().remove("cid"); + Integer lac = (Integer) position.getAttributes().remove("lac"); + if (cid != null && lac != null) { CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); long operator = position.getInteger(Position.KEY_OPERATOR); if (operator >= 1000) { @@ -387,7 +367,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeLocation(Position position, ByteBuf buf, int codec) { + private void decodeLocation(Position position, ByteBuf buf, int codec, String model) { int globalMask = 0x0f; @@ -484,7 +464,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 1)) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 1, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 1, codec, model); } } @@ -492,7 +472,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 2)) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 2, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 2, codec, model); } } @@ -500,7 +480,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 3)) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 4, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 4, codec, model); } } @@ -508,7 +488,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_8 || codec == CODEC_8_EXT || codec == CODEC_16) { int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8, codec, model); } } @@ -578,10 +558,10 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { int count = buf.readUnsignedByte(); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession == null) { return null; } + String model = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel(); for (int i = 0; i < count; i++) { Position position = new Position(getProtocolName()); @@ -603,7 +583,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } else if (codec == CODEC_12) { decodeSerial(channel, remoteAddress, deviceSession, position, buf); } else { - decodeLocation(position, buf, codec); + decodeLocation(position, buf, codec, model); } if (!position.getOutdated() || !position.getAttributes().isEmpty()) { -- cgit v1.2.3 From 910965c3d08745d68cbf812ed96eef7323dbb893 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 1 Aug 2022 19:06:04 -0700 Subject: Handle GPS103 no GPS (fix #4915) --- src/main/java/org/traccar/helper/Parser.java | 13 +++++++------ .../java/org/traccar/protocol/Gps103ProtocolDecoder.java | 15 ++++++++++----- .../org/traccar/protocol/Gps103ProtocolDecoderTest.java | 6 +++++- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/traccar/helper/Parser.java b/src/main/java/org/traccar/helper/Parser.java index 22e98ded1..aa39e1ad7 100644 --- a/src/main/java/org/traccar/helper/Parser.java +++ b/src/main/java/org/traccar/helper/Parser.java @@ -48,13 +48,14 @@ public class Parser { } public boolean hasNext(int number) { - String value = matcher.group(position); - if (value != null && !value.isEmpty()) { - return true; - } else { - position += number; - return false; + for (int i = position; i < position + number; i++) { + String value = matcher.group(i); + if (value != null && !value.isEmpty()) { + return true; + } } + position += number; + return false; } public String next() { diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index b63bcd0c0..28efa3c30 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -56,9 +56,12 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { .groupEnd() .expression("([^,]+)?,") // rfid .groupBegin() - .text("L,,,") + .text("L,") + .groupBegin() + .text(",,") .number("(x+),,") // lac .number("(x+),,,") // cid + .groupEnd("?") .or() .text("F,") .groupBegin() @@ -218,13 +221,11 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext(2)) { - - getLastLocation(position, null); - position.setNetwork(new Network(CellTower.fromLacCid( getConfig(), parser.nextHexInt(0), parser.nextHexInt(0)))); + } - } else { + if (parser.hasNext(20)) { String utcHours = parser.next(); String utcMinutes = parser.next(); @@ -262,6 +263,10 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { position.set("fuel2", parser.nextDouble()); position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); + } else { + + getLastLocation(position, null); + } return position; diff --git a/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java index 425fcd8ae..cf5786d75 100644 --- a/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gps103ProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class Gps103ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gps103ProtocolDecoder(null)); + verifyAttribute(decoder, text( + "imei:865456055519122,sensor alarm,2208011920,,L,;"), + Position.KEY_ALARM, Position.ALARM_VIBRATION); + verifyPosition(decoder, text( "imei:864035050002451,tracker,201223064947,,F,064947,A,1935.70640,N,09859.94436,W,0.025,;")); @@ -155,7 +159,7 @@ public class Gps103ProtocolDecoderTest extends ProtocolTest { "359586015829802")); // No GPS signal - verifyNull(decoder, text( + verifyNotNull(decoder, text( "imei:359586015829802,tracker,000000000,13554900601,L,;")); verifyPosition(decoder, text( -- cgit v1.2.3 From ab6970135850655313e257cf44fb68c67e9f1e80 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 2 Aug 2022 19:16:11 -0700 Subject: New API token system --- schema/changelog-5.3.xml | 2 + .../org/traccar/api/resource/SessionResource.java | 30 ++++++++-- .../org/traccar/api/security/LoginService.java | 13 ++++- .../api/security/SecurityRequestFilter.java | 4 +- .../org/traccar/api/signature/CryptoManager.java | 25 +++++---- .../org/traccar/api/signature/TokenManager.java | 64 ++++++++++++++++++++++ src/main/java/org/traccar/model/User.java | 17 ------ 7 files changed, 117 insertions(+), 38 deletions(-) create mode 100644 src/main/java/org/traccar/api/signature/TokenManager.java diff --git a/schema/changelog-5.3.xml b/schema/changelog-5.3.xml index a689bc236..3b103a6fa 100644 --- a/schema/changelog-5.3.xml +++ b/schema/changelog-5.3.xml @@ -32,6 +32,8 @@
+ + diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 8eabdc63c..f70b67cde 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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.api.resource; import org.traccar.api.BaseResource; import org.traccar.api.security.LoginService; +import org.traccar.api.signature.TokenManager; import org.traccar.helper.DataConverter; import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; @@ -40,12 +41,16 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.io.UnsupportedEncodingException; +import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.util.Date; +import java.util.concurrent.TimeUnit; @Path("session") @Produces(MediaType.APPLICATION_JSON) @@ -59,12 +64,15 @@ public class SessionResource extends BaseResource { @Inject private LoginService loginService; - @javax.ws.rs.core.Context + @Inject + private TokenManager tokenManager; + + @Context private HttpServletRequest request; @PermitAll @GET - public User get(@QueryParam("token") String token) throws StorageException, UnsupportedEncodingException { + public User get(@QueryParam("token") String token) throws StorageException, IOException, GeneralSecurityException { if (token != null) { User user = loginService.login(token); @@ -84,11 +92,11 @@ public class SessionResource extends BaseResource { for (Cookie cookie : cookies) { if (cookie.getName().equals(USER_COOKIE_KEY)) { byte[] emailBytes = DataConverter.parseBase64( - URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII.name())); + URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); email = new String(emailBytes, StandardCharsets.UTF_8); } else if (cookie.getName().equals(PASS_COOKIE_KEY)) { byte[] passwordBytes = DataConverter.parseBase64( - URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII.name())); + URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII)); password = new String(passwordBytes, StandardCharsets.UTF_8); } } @@ -144,4 +152,14 @@ public class SessionResource extends BaseResource { return Response.noContent().build(); } + @Path("token") + @POST + public String requestToken( + @FormParam("expiration") Date expiration) throws StorageException, GeneralSecurityException, IOException { + if (expiration == null) { + expiration = new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(7)); + } + return tokenManager.generateToken(getUserId(), expiration); + } + } diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 104a6fac3..1e82a4cf2 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -15,6 +15,7 @@ */ package org.traccar.api.security; +import org.traccar.api.signature.TokenManager; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; @@ -27,29 +28,35 @@ import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; +import java.io.IOException; +import java.security.GeneralSecurityException; public class LoginService { private final Storage storage; + private final TokenManager tokenManager; private final LdapProvider ldapProvider; private final String serviceAccountToken; private final boolean forceLdap; @Inject - public LoginService(Config config, Storage storage, @Nullable LdapProvider ldapProvider) { + public LoginService( + Config config, Storage storage, TokenManager tokenManager, @Nullable LdapProvider ldapProvider) { this.storage = storage; + this.tokenManager = tokenManager; this.ldapProvider = ldapProvider; serviceAccountToken = config.getString(Keys.WEB_SERVICE_ACCOUNT_TOKEN); forceLdap = config.getBoolean(Keys.LDAP_FORCE); } - public User login(String token) throws StorageException { + public User login(String token) throws StorageException, GeneralSecurityException, IOException { if (serviceAccountToken != null && serviceAccountToken.equals(token)) { return new ServiceAccountUser(); } + long userId = tokenManager.verifyToken(token); User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("token", "token", token))); + new Columns.All(), new Condition.Equals("id", "id", userId))); if (user != null) { checkUserEnabled(user); } diff --git a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java index ada7bf997..94b6bbf05 100644 --- a/src/main/java/org/traccar/api/security/SecurityRequestFilter.java +++ b/src/main/java/org/traccar/api/security/SecurityRequestFilter.java @@ -33,8 +33,10 @@ import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +import java.io.IOException; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; public class SecurityRequestFilter implements ContainerRequestFilter { @@ -94,7 +96,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { statisticsManager.registerRequest(user.getId()); securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); } - } catch (StorageException e) { + } catch (StorageException | GeneralSecurityException | IOException e) { throw new WebApplicationException(e); } diff --git a/src/main/java/org/traccar/api/signature/CryptoManager.java b/src/main/java/org/traccar/api/signature/CryptoManager.java index ea59dcd70..8a3e7704c 100644 --- a/src/main/java/org/traccar/api/signature/CryptoManager.java +++ b/src/main/java/org/traccar/api/signature/CryptoManager.java @@ -15,7 +15,6 @@ */ package org.traccar.api.signature; -import org.traccar.helper.DataConverter; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -46,28 +45,32 @@ public class CryptoManager { this.storage = storage; } - public String sign(String data) throws GeneralSecurityException, StorageException { + public byte[] sign(byte[] data) throws GeneralSecurityException, StorageException { if (privateKey == null) { initializeKeys(); } Signature signature = Signature.getInstance("SHA256withECDSA"); signature.initSign(privateKey); - signature.update(data.getBytes()); - return data + '.' + DataConverter.printBase64(signature.sign()); + signature.update(data); + byte[] block = signature.sign(); + byte[] combined = new byte[1 + block.length + data.length]; + combined[0] = (byte) block.length; + System.arraycopy(block, 0, combined, 1, block.length); + System.arraycopy(data, 0, combined, 1 + block.length, data.length); + return combined; } - public String verify(String data) throws GeneralSecurityException, StorageException { + public byte[] verify(byte[] data) throws GeneralSecurityException, StorageException { if (publicKey == null) { initializeKeys(); } Signature signature = Signature.getInstance("SHA256withECDSA"); signature.initVerify(publicKey); - - int delimiter = data.lastIndexOf('.'); - String originalData = data.substring(0, delimiter); - - signature.update(originalData.getBytes()); - if (!signature.verify(DataConverter.parseBase64(data.substring(delimiter + 1)))) { + int length = data[0]; + byte[] originalData = new byte[data.length - 1 - length]; + System.arraycopy(data, 1 + length, originalData, 0, originalData.length); + signature.update(originalData); + if (!signature.verify(data, 1, length)) { throw new SecurityException("Invalid signature"); } return originalData; diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java new file mode 100644 index 000000000..3f39d5380 --- /dev/null +++ b/src/main/java/org/traccar/api/signature/TokenManager.java @@ -0,0 +1,64 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.api.signature; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.codec.binary.Base64; +import org.traccar.storage.StorageException; + +import javax.inject.Inject; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.Date; + +public class TokenManager { + + private final ObjectMapper objectMapper; + private final CryptoManager cryptoManager; + + public static class Data { + @JsonProperty("u") + private long userId; + @JsonProperty("e") + private Date expiration; + } + + @Inject + public TokenManager(ObjectMapper objectMapper, CryptoManager cryptoManager) { + this.objectMapper = objectMapper; + this.cryptoManager = cryptoManager; + } + + public String generateToken( + long userId, Date expiration) throws IOException, GeneralSecurityException, StorageException { + Data data = new Data(); + data.userId = userId; + data.expiration = expiration; + byte[] encoded = objectMapper.writeValueAsBytes(data); + return Base64.encodeBase64URLSafeString(cryptoManager.sign(encoded)); + } + + public long verifyToken(String token) throws IOException, GeneralSecurityException, StorageException { + byte[] encoded = cryptoManager.verify(Base64.decodeBase64(token)); + Data data = objectMapper.readValue(encoded, Data.class); + if (data.expiration.before(new Date())) { + throw new SecurityException("Token has expired"); + } + return data.userId; + } + +} diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 3db20c753..53594fe07 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -208,23 +208,6 @@ public class User extends ExtendedModel implements UserRestrictions, Disableable this.deviceReadonly = deviceReadonly; } - private String token; - - public String getToken() { - return token; - } - - public void setToken(String token) { - if (token != null && !token.isEmpty()) { - if (!token.matches("^[a-zA-Z0-9-]{16,}$")) { - throw new IllegalArgumentException("Illegal token"); - } - this.token = token; - } else { - this.token = null; - } - } - private boolean limitCommands; @Override -- cgit v1.2.3 From 62e4876406de1951705e76f85c1e099c36d48a87 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 2 Aug 2022 20:40:29 -0700 Subject: New tokens for password reset --- .../org/traccar/api/resource/PasswordResource.java | 33 +++++++++++----------- .../org/traccar/api/resource/SessionResource.java | 3 -- .../org/traccar/api/signature/TokenManager.java | 9 +++++- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 91c2d8ecf..1fb08b02a 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -16,6 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; +import org.traccar.api.signature.TokenManager; import org.traccar.mail.MailManager; import org.traccar.model.User; import org.traccar.notification.TextTemplateFormatter; @@ -34,35 +35,34 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.UUID; +import java.io.IOException; +import java.security.GeneralSecurityException; @Path("password") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public class PasswordResource extends BaseResource { - private static final String PASSWORD_RESET_TOKEN = "passwordToken"; - @Inject private MailManager mailManager; + @Inject + private TokenManager tokenManager; + @Inject private TextTemplateFormatter textTemplateFormatter; @Path("reset") @PermitAll @POST - public Response reset(@FormParam("email") String email) throws StorageException, MessagingException { + public Response reset(@FormParam("email") String email) + throws StorageException, MessagingException, GeneralSecurityException, IOException { + User user = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Equals("email", "email", email))); if (user != null) { - String token = UUID.randomUUID().toString().replaceAll("-", ""); - user.set(PASSWORD_RESET_TOKEN, token); - storage.updateObject(user, new Request( - new Columns.Include("attributes"), new Condition.Equals("id", "id"))); - var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); - velocityContext.put("token", token); + velocityContext.put("token", tokenManager.generateToken(user.getId(), null)); var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } @@ -73,15 +73,16 @@ public class PasswordResource extends BaseResource { @PermitAll @POST public Response update( - @FormParam("token") String token, @FormParam("password") String password) throws StorageException { - User user = storage.getObjects(User.class, new Request(new Columns.All())).stream() - .filter(it -> token.equals(it.getString(PASSWORD_RESET_TOKEN))) - .findFirst().orElse(null); + @FormParam("token") String token, @FormParam("password") String password) + throws StorageException, GeneralSecurityException, IOException { + + long userId = tokenManager.verifyToken(token); + User user = storage.getObject(User.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", userId))); if (user != null) { - user.getAttributes().remove(PASSWORD_RESET_TOKEN); user.setPassword(password); storage.updateObject(user, new Request( - new Columns.Include("attributes", "hashedPassword", "salt"), new Condition.Equals("id", "id"))); + new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); return Response.ok().build(); } return Response.status(Response.Status.NOT_FOUND).build(); diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index f70b67cde..61c3a5885 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -156,9 +156,6 @@ public class SessionResource extends BaseResource { @POST public String requestToken( @FormParam("expiration") Date expiration) throws StorageException, GeneralSecurityException, IOException { - if (expiration == null) { - expiration = new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(7)); - } return tokenManager.generateToken(getUserId(), expiration); } diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java index 3f39d5380..a51234a95 100644 --- a/src/main/java/org/traccar/api/signature/TokenManager.java +++ b/src/main/java/org/traccar/api/signature/TokenManager.java @@ -24,9 +24,12 @@ import javax.inject.Inject; import java.io.IOException; import java.security.GeneralSecurityException; import java.util.Date; +import java.util.concurrent.TimeUnit; public class TokenManager { + private static final int DEFAULT_EXPIRATION_DAYS = 7; + private final ObjectMapper objectMapper; private final CryptoManager cryptoManager; @@ -47,7 +50,11 @@ public class TokenManager { long userId, Date expiration) throws IOException, GeneralSecurityException, StorageException { Data data = new Data(); data.userId = userId; - data.expiration = expiration; + if (expiration != null) { + data.expiration = expiration; + } else { + data.expiration = new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(DEFAULT_EXPIRATION_DAYS)); + } byte[] encoded = objectMapper.writeValueAsBytes(data); return Base64.encodeBase64URLSafeString(cryptoManager.sign(encoded)); } -- cgit v1.2.3 From bd55a835340547aabc3f401bb97e181a3e70df8f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 2 Aug 2022 20:44:34 -0700 Subject: Remove unused import --- src/main/java/org/traccar/api/resource/SessionResource.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 61c3a5885..05f492d73 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -19,8 +19,8 @@ import org.traccar.api.BaseResource; import org.traccar.api.security.LoginService; import org.traccar.api.signature.TokenManager; import org.traccar.helper.DataConverter; -import org.traccar.helper.ServletHelper; import org.traccar.helper.LogAction; +import org.traccar.helper.ServletHelper; import org.traccar.model.User; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -44,13 +44,11 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; - import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.util.Date; -import java.util.concurrent.TimeUnit; @Path("session") @Produces(MediaType.APPLICATION_JSON) -- cgit v1.2.3 From bb7bdcfc3389b6822b7680837386e3650962f30a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 2 Aug 2022 21:01:06 -0700 Subject: Notifications unsubscribe option --- .../java/org/traccar/api/resource/PasswordResource.java | 2 +- src/main/java/org/traccar/api/signature/TokenManager.java | 4 ++++ .../org/traccar/notification/TextTemplateFormatter.java | 13 ++++++++++++- templates/full/alarm.vm | 4 +++- templates/full/commandResult.vm | 4 +++- templates/full/deviceFuelDrop.vm | 2 ++ templates/full/deviceInactive.vm | 4 +++- templates/full/deviceMoving.vm | 2 ++ templates/full/deviceOffline.vm | 4 +++- templates/full/deviceOnline.vm | 4 +++- templates/full/deviceOverspeed.vm | 2 ++ templates/full/deviceStopped.vm | 2 ++ templates/full/deviceUnknown.vm | 4 +++- templates/full/driverChanged.vm | 4 +++- templates/full/geofenceEnter.vm | 2 ++ templates/full/geofenceExit.vm | 2 ++ templates/full/ignitionOff.vm | 2 ++ templates/full/ignitionOn.vm | 2 ++ templates/full/maintenance.vm | 2 ++ templates/full/media.vm | 4 +++- templates/full/textMessage.vm | 2 ++ 21 files changed, 61 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 1fb08b02a..625ff4cb1 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -62,7 +62,7 @@ public class PasswordResource extends BaseResource { new Columns.All(), new Condition.Equals("email", "email", email))); if (user != null) { var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); - velocityContext.put("token", tokenManager.generateToken(user.getId(), null)); + velocityContext.put("token", tokenManager.generateToken(user.getId())); var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java index a51234a95..a352ecc10 100644 --- a/src/main/java/org/traccar/api/signature/TokenManager.java +++ b/src/main/java/org/traccar/api/signature/TokenManager.java @@ -46,6 +46,10 @@ public class TokenManager { this.cryptoManager = cryptoManager; } + public String generateToken(long userId) throws IOException, GeneralSecurityException, StorageException { + return generateToken(userId, null); + } + public String generateToken( long userId, Date expiration) throws IOException, GeneralSecurityException, StorageException { Data data = new Data(); diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index bca18f53c..be894af96 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -23,14 +23,18 @@ import org.apache.velocity.tools.generic.DateTool; import org.apache.velocity.tools.generic.NumberTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.api.signature.TokenManager; import org.traccar.helper.model.UserUtil; import org.traccar.model.Server; import org.traccar.model.User; +import org.traccar.storage.StorageException; import javax.inject.Inject; +import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; +import java.security.GeneralSecurityException; import java.util.Locale; public class TextTemplateFormatter { @@ -38,10 +42,12 @@ public class TextTemplateFormatter { private static final Logger LOGGER = LoggerFactory.getLogger(TextTemplateFormatter.class); private final VelocityEngine velocityEngine; + private final TokenManager tokenManager; @Inject - public TextTemplateFormatter(VelocityEngine velocityEngine) { + public TextTemplateFormatter(VelocityEngine velocityEngine, TokenManager tokenManager) { this.velocityEngine = velocityEngine; + this.tokenManager = tokenManager; } public VelocityContext prepareContext(Server server, User user) { @@ -51,6 +57,11 @@ public class TextTemplateFormatter { if (user != null) { velocityContext.put("user", user); velocityContext.put("timezone", UserUtil.getTimezone(server, user)); + try { + velocityContext.put("token", tokenManager.generateToken(user.getId())); + } catch (IOException | GeneralSecurityException | StorageException e) { + LOGGER.warn("Token generation failed", e); + } } velocityContext.put("webUrl", velocityEngine.getProperty("web.url")); diff --git a/templates/full/alarm.vm b/templates/full/alarm.vm index 8eac3930a..5d367dc3a 100644 --- a/templates/full/alarm.vm +++ b/templates/full/alarm.vm @@ -6,5 +6,7 @@ Device: $device.name
Alarm: $position.getString("alarm")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe - + diff --git a/templates/full/commandResult.vm b/templates/full/commandResult.vm index 443e1a399..c3b62edf5 100644 --- a/templates/full/commandResult.vm +++ b/templates/full/commandResult.vm @@ -5,6 +5,8 @@ Device: $device.name
Result: $position.getString("result")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/deviceFuelDrop.vm b/templates/full/deviceFuelDrop.vm index bf7a16b97..3fb9aa63c 100644 --- a/templates/full/deviceFuelDrop.vm +++ b/templates/full/deviceFuelDrop.vm @@ -5,5 +5,7 @@ Device: $device.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/deviceInactive.vm b/templates/full/deviceInactive.vm index 626db1dc4..01fa319b5 100644 --- a/templates/full/deviceInactive.vm +++ b/templates/full/deviceInactive.vm @@ -7,6 +7,8 @@ Device: $device.name
Inactive
Last Update: $dateTool.format("YYYY-MM-dd HH:mm:ss", $lastUpdate, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/deviceMoving.vm b/templates/full/deviceMoving.vm index b22b90428..e3941b324 100644 --- a/templates/full/deviceMoving.vm +++ b/templates/full/deviceMoving.vm @@ -6,5 +6,7 @@ Device: $device.name
Moving
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/deviceOffline.vm b/templates/full/deviceOffline.vm index 332bfe3d9..8f2c515b2 100644 --- a/templates/full/deviceOffline.vm +++ b/templates/full/deviceOffline.vm @@ -5,6 +5,8 @@ Device: $device.name
Offline
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/deviceOnline.vm b/templates/full/deviceOnline.vm index 3ca3cfa9b..81a4ccbc8 100644 --- a/templates/full/deviceOnline.vm +++ b/templates/full/deviceOnline.vm @@ -5,6 +5,8 @@ Device: $device.name
Online
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/deviceOverspeed.vm b/templates/full/deviceOverspeed.vm index f303b734c..5f38b3f88 100644 --- a/templates/full/deviceOverspeed.vm +++ b/templates/full/deviceOverspeed.vm @@ -15,5 +15,7 @@ Device: $device.name
Exceeds the speed: $speedString#{if}($geofence) in $geofence.name#{else}#{end}
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/deviceStopped.vm b/templates/full/deviceStopped.vm index 9f8a30707..e3246b277 100644 --- a/templates/full/deviceStopped.vm +++ b/templates/full/deviceStopped.vm @@ -6,5 +6,7 @@ Device: $device.name
Stopped
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/deviceUnknown.vm b/templates/full/deviceUnknown.vm index 0e6e9b4b4..e012845e6 100644 --- a/templates/full/deviceUnknown.vm +++ b/templates/full/deviceUnknown.vm @@ -5,6 +5,8 @@ Device: $device.name
Status is unknown
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/driverChanged.vm b/templates/full/driverChanged.vm index 65e2768b5..f9b6d0ae2 100644 --- a/templates/full/driverChanged.vm +++ b/templates/full/driverChanged.vm @@ -5,6 +5,8 @@ Device: $device.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
-Driver: #{if}($driver)$driver.name#{else}$event.getString("driverUniqueId")#{end} +Driver: #{if}($driver)$driver.name#{else}$event.getString("driverUniqueId")#{end}
+
+Unsubscribe diff --git a/templates/full/geofenceEnter.vm b/templates/full/geofenceEnter.vm index 2d9cd3613..5ae14a8d3 100644 --- a/templates/full/geofenceEnter.vm +++ b/templates/full/geofenceEnter.vm @@ -6,5 +6,7 @@ Device: $device.name
Has entered geofence: $geofence.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/geofenceExit.vm b/templates/full/geofenceExit.vm index ae1eb5520..08887a93a 100644 --- a/templates/full/geofenceExit.vm +++ b/templates/full/geofenceExit.vm @@ -6,5 +6,7 @@ Device: $device.name
Has exited geofence: $geofence.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/ignitionOff.vm b/templates/full/ignitionOff.vm index 0ec50918b..a43e4aabb 100644 --- a/templates/full/ignitionOff.vm +++ b/templates/full/ignitionOff.vm @@ -6,5 +6,7 @@ Device: $device.name
Ignition OFF
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/ignitionOn.vm b/templates/full/ignitionOn.vm index 7e0d6532d..1ba9ef030 100644 --- a/templates/full/ignitionOn.vm +++ b/templates/full/ignitionOn.vm @@ -6,5 +6,7 @@ Device: $device.name
Ignition ON
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/maintenance.vm b/templates/full/maintenance.vm index 798de637d..39ccb21bc 100644 --- a/templates/full/maintenance.vm +++ b/templates/full/maintenance.vm @@ -6,5 +6,7 @@ Device: $device.name
Maintenance is required: $maintenance.name
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe diff --git a/templates/full/media.vm b/templates/full/media.vm index 6651deffc..1c94265fb 100644 --- a/templates/full/media.vm +++ b/templates/full/media.vm @@ -6,6 +6,8 @@ Device: $device.name
Type: $event.getString("media")
File: $event.getString("file")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
-Link: $webUrl?eventId=$event.id +Link: $webUrl?eventId=$event.id
+
+Unsubscribe diff --git a/templates/full/textMessage.vm b/templates/full/textMessage.vm index 7222b4d91..fb20275e3 100644 --- a/templates/full/textMessage.vm +++ b/templates/full/textMessage.vm @@ -5,5 +5,7 @@ Device: $device.name
Message: $event.getString("message")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
+
+Unsubscribe -- cgit v1.2.3 From 38961efd25373f290bb20780f770d17b425de88c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Aug 2022 08:35:57 -0700 Subject: Implement GPX export (fix #4646) --- .../org/traccar/api/resource/PositionResource.java | 22 +++++++ .../org/traccar/reports/GpxExportProvider.java | 76 ++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 src/main/java/org/traccar/reports/GpxExportProvider.java diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index b4c8d18b9..7d7921085 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -21,6 +21,7 @@ import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.UserRestrictions; import org.traccar.reports.CsvExportProvider; +import org.traccar.reports.GpxExportProvider; import org.traccar.reports.KmlExportProvider; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -54,6 +55,9 @@ public class PositionResource extends BaseResource { @Inject private CsvExportProvider csvExportProvider; + @Inject + private GpxExportProvider gpxExportProvider; + @GET public Collection getJson( @QueryParam("deviceId") long deviceId, @QueryParam("id") List positionIds, @@ -118,4 +122,22 @@ public class PositionResource extends BaseResource { .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.csv").build(); } + @Path("gpx") + @GET + @Produces("application/gpx+xml") + public Response getGpx( + @QueryParam("deviceId") long deviceId, + @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException { + permissionsService.checkPermission(Device.class, getUserId(), deviceId); + StreamingOutput stream = output -> { + try { + gpxExportProvider.generate(output, deviceId, from, to); + } catch (StorageException e) { + throw new WebApplicationException(e); + } + }; + return Response.ok(stream) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.gpx").build(); + } + } diff --git a/src/main/java/org/traccar/reports/GpxExportProvider.java b/src/main/java/org/traccar/reports/GpxExportProvider.java new file mode 100644 index 000000000..f1a0f292d --- /dev/null +++ b/src/main/java/org/traccar/reports/GpxExportProvider.java @@ -0,0 +1,76 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.reports; + +import org.traccar.helper.DateUtil; +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Device; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; + +import javax.inject.Inject; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.Date; + +public class GpxExportProvider { + + private final Storage storage; + + @Inject + public GpxExportProvider(Storage storage) { + this.storage = storage; + } + + public void generate( + OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { + + var device = storage.getObject(Device.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", deviceId))); + var positions = PositionUtil.getPositions(storage, deviceId, from, to); + + try (PrintWriter writer = new PrintWriter(outputStream)) { + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(""); + writer.print(device.getName()); + writer.print(""); + writer.print(""); + positions.forEach(position -> { + writer.print(""); + writer.print(""); + writer.print(position.getAltitude()); + writer.print(""); + writer.print(""); + writer.print(""); + }); + writer.print(""); + writer.print(""); + writer.print(""); + } + } + +} -- cgit v1.2.3 From 45cec80f310c966b63388b18a773533d0e9b9102 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Aug 2022 16:57:14 -0700 Subject: Fix index usage --- src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index d8a753abe..3ff8eb2fb 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -239,7 +239,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { private Object decodePositions(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - int length = (buf.readUnsignedShortLE() & 0x7fff) + 3; + int endIndex = (buf.readUnsignedShortLE() & 0x7fff) + buf.readerIndex(); List positions = new LinkedList<>(); Set tags = new HashSet<>(); @@ -248,7 +248,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = null; Position position = new Position(getProtocolName()); - while (buf.readerIndex() < length) { + while (buf.readerIndex() < endIndex) { int tag = buf.readUnsignedByte(); if (tags.contains(tag)) { -- cgit v1.2.3 From 3e6929ff362d53aea19516cb5b903d1d753e8ddc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Aug 2022 17:22:26 -0700 Subject: Add GalileoSky Iridium format --- .../traccar/protocol/GalileoProtocolDecoder.java | 40 ++++++++++++++++++++-- .../protocol/GalileoProtocolDecoderTest.java | 3 ++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index 3ff8eb2fb..b1deded3b 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BitUtil; import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; @@ -229,7 +230,11 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { int header = buf.readUnsignedByte(); if (header == 0x01) { - return decodePositions(channel, remoteAddress, buf); + if (buf.getUnsignedMedium(buf.readerIndex() + 2) == 0x01001c) { + return decodeIridiumPosition(channel, remoteAddress, buf); + } else { + return decodePositions(channel, remoteAddress, buf); + } } else if (header == 0x07) { return decodePhoto(channel, remoteAddress, buf); } @@ -237,7 +242,38 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodePositions(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + private Position decodeIridiumPosition(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + + buf.readUnsignedShortLE(); // length + + buf.skipBytes(3); // identification header + buf.readUnsignedIntLE(); // index + + DeviceSession deviceSession = getDeviceSession( + channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII)); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + buf.readUnsignedByte(); // session status + buf.skipBytes(4); // reserved + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + + buf.skipBytes(3); // coordinates header + int flags = buf.readUnsignedByte(); + double latitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; + double longitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; + position.setLatitude(BitUtil.check(flags, 1) ? -latitude : latitude); + position.setLongitude(BitUtil.check(flags, 0) ? -longitude : longitude); + position.setAccuracy(buf.readUnsignedIntLE()); + + return position; + } + + private List decodePositions(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { int endIndex = (buf.readUnsignedShortLE() & 0x7fff) + buf.readerIndex(); diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java index f9bdd6b42..f676b1cc1 100644 --- a/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GalileoProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new GalileoProtocolDecoder(null)); + verifyNotNull(decoder, binary( + "01006501001c05cf1f8133303032333430363939303130313000004a000062d8f3ee03000b000f85402088970000000602003503333030323334303639393031303130100000207af3d862300cbe08ee00acfaf001330000760634b301350840090a416b2f42920e")); + verifyPositions(decoder, binary( "011801018202130338363833343530333230343234323604640010a406207caa9f5b300c830a7901ca0ec802330000000034b802350540003e41703f422b1043234504004600e09000000000a000a100a200a300a400a500a600a700a800a900aa00ab00ac00ad00ae00af00b00000b10000b20000b30000b40000b50000b60000b70000b80000b90000c000000000c100000000c200000000c300000000c400c500c600c700c800c900ca00cb00cc00cd00ce00cf00d000d100d200d4d3140000d60000d70000d80000d90000da0000db00000000dc00000000dd00000000de00000000df00000000f000000000f100000000f200000000f300000000f400000000f500000000f600000000f700000000f800000000f9000000008960")); -- cgit v1.2.3 From 6d1923bd6b4841eac9d1a383e1eafe6cab30ce8c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Aug 2022 18:50:54 -0700 Subject: Rename fuel event handler --- src/main/java/org/traccar/BasePipelineFactory.java | 4 +- .../handler/events/FuelDropEventHandler.java | 71 ---------------------- .../traccar/handler/events/FuelEventHandler.java | 71 ++++++++++++++++++++++ 3 files changed, 73 insertions(+), 73 deletions(-) delete mode 100644 src/main/java/org/traccar/handler/events/FuelDropEventHandler.java create mode 100644 src/main/java/org/traccar/handler/events/FuelEventHandler.java diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index fb48f81d1..0d91ec7e4 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -45,7 +45,7 @@ import org.traccar.handler.events.AlertEventHandler; import org.traccar.handler.events.BehaviorEventHandler; import org.traccar.handler.events.CommandResultEventHandler; import org.traccar.handler.events.DriverEventHandler; -import org.traccar.handler.events.FuelDropEventHandler; +import org.traccar.handler.events.FuelEventHandler; import org.traccar.handler.events.GeofenceEventHandler; import org.traccar.handler.events.IgnitionEventHandler; import org.traccar.handler.events.MaintenanceEventHandler; @@ -146,7 +146,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { CommandResultEventHandler.class, OverspeedEventHandler.class, BehaviorEventHandler.class, - FuelDropEventHandler.class, + FuelEventHandler.class, MotionEventHandler.class, GeofenceEventHandler.class, AlertEventHandler.class, diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java deleted file mode 100644 index 25ae1fadb..000000000 --- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2017 - 2022 Anton Tananaev (anton@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.handler.events; - -import io.netty.channel.ChannelHandler; -import org.traccar.config.Keys; -import org.traccar.helper.model.AttributeUtil; -import org.traccar.helper.model.PositionUtil; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Position; -import org.traccar.session.cache.CacheManager; - -import javax.inject.Inject; -import java.util.Collections; -import java.util.Map; - -@ChannelHandler.Sharable -public class FuelDropEventHandler extends BaseEventHandler { - - private final CacheManager cacheManager; - - @Inject - public FuelDropEventHandler(CacheManager cacheManager) { - this.cacheManager = cacheManager; - } - - @Override - protected Map analyzePosition(Position position) { - - Device device = cacheManager.getObject(Device.class, position.getDeviceId()); - if (device == null) { - return null; - } - if (!PositionUtil.isLatest(cacheManager, position)) { - return null; - } - - double fuelDropThreshold = AttributeUtil.lookup( - cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); - if (fuelDropThreshold > 0) { - Position lastPosition = cacheManager.getPosition(position.getDeviceId()); - if (position.hasAttribute(Position.KEY_FUEL_LEVEL) - && lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) { - - double drop = lastPosition.getDouble(Position.KEY_FUEL_LEVEL) - - position.getDouble(Position.KEY_FUEL_LEVEL); - if (drop >= fuelDropThreshold) { - Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position); - return Collections.singletonMap(event, position); - } - } - } - - return null; - } - -} diff --git a/src/main/java/org/traccar/handler/events/FuelEventHandler.java b/src/main/java/org/traccar/handler/events/FuelEventHandler.java new file mode 100644 index 000000000..9ec819a5f --- /dev/null +++ b/src/main/java/org/traccar/handler/events/FuelEventHandler.java @@ -0,0 +1,71 @@ +/* + * Copyright 2017 - 2022 Anton Tananaev (anton@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.handler.events; + +import io.netty.channel.ChannelHandler; +import org.traccar.config.Keys; +import org.traccar.helper.model.AttributeUtil; +import org.traccar.helper.model.PositionUtil; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; + +import javax.inject.Inject; +import java.util.Collections; +import java.util.Map; + +@ChannelHandler.Sharable +public class FuelEventHandler extends BaseEventHandler { + + private final CacheManager cacheManager; + + @Inject + public FuelEventHandler(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + @Override + protected Map analyzePosition(Position position) { + + Device device = cacheManager.getObject(Device.class, position.getDeviceId()); + if (device == null) { + return null; + } + if (!PositionUtil.isLatest(cacheManager, position)) { + return null; + } + + double fuelDropThreshold = AttributeUtil.lookup( + cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); + if (fuelDropThreshold > 0) { + Position lastPosition = cacheManager.getPosition(position.getDeviceId()); + if (position.hasAttribute(Position.KEY_FUEL_LEVEL) + && lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) { + + double drop = lastPosition.getDouble(Position.KEY_FUEL_LEVEL) + - position.getDouble(Position.KEY_FUEL_LEVEL); + if (drop >= fuelDropThreshold) { + Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position); + return Collections.singletonMap(event, position); + } + } + } + + return null; + } + +} -- cgit v1.2.3 From 074cc52c3d645ac974a1489aa4e197d471093403 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 3 Aug 2022 19:06:12 -0700 Subject: Implement refuel events --- src/main/java/org/traccar/config/Keys.java | 9 +++++++ .../traccar/handler/events/FuelEventHandler.java | 28 +++++++++++++--------- src/main/java/org/traccar/model/Event.java | 1 + templates/full/deviceFuelIncrease.vm | 11 +++++++++ templates/short/deviceFuelIncrease.vm | 2 ++ 5 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 templates/full/deviceFuelIncrease.vm create mode 100644 templates/short/deviceFuelIncrease.vm diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index e97e104a1..a3b39581d 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -309,6 +309,15 @@ public final class Keys { List.of(KeyType.SERVER, KeyType.DEVICE), 0.0); + /** + * Fuel increase threshold value. When fuel level increases from one position to another for more the value, an + * event is generated. + */ + public static final ConfigKey EVENT_FUEL_INCREASE_THRESHOLD = new DoubleConfigKey( + "fuelIncreaseThreshold", + List.of(KeyType.SERVER, KeyType.DEVICE), + 0.0); + /** * Speed limit value in knots. */ diff --git a/src/main/java/org/traccar/handler/events/FuelEventHandler.java b/src/main/java/org/traccar/handler/events/FuelEventHandler.java index 9ec819a5f..d5d4ab9be 100644 --- a/src/main/java/org/traccar/handler/events/FuelEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelEventHandler.java @@ -25,7 +25,6 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; -import java.util.Collections; import java.util.Map; @ChannelHandler.Sharable @@ -49,18 +48,25 @@ public class FuelEventHandler extends BaseEventHandler { return null; } - double fuelDropThreshold = AttributeUtil.lookup( - cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); - if (fuelDropThreshold > 0) { + if (position.hasAttribute(Position.KEY_FUEL_LEVEL)) { Position lastPosition = cacheManager.getPosition(position.getDeviceId()); - if (position.hasAttribute(Position.KEY_FUEL_LEVEL) - && lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) { + if (lastPosition != null && lastPosition.hasAttribute(Position.KEY_FUEL_LEVEL)) { + double before = lastPosition.getDouble(Position.KEY_FUEL_LEVEL); + double after = position.getDouble(Position.KEY_FUEL_LEVEL); + double change = after - before; - double drop = lastPosition.getDouble(Position.KEY_FUEL_LEVEL) - - position.getDouble(Position.KEY_FUEL_LEVEL); - if (drop >= fuelDropThreshold) { - Event event = new Event(Event.TYPE_DEVICE_FUEL_DROP, position); - return Collections.singletonMap(event, position); + if (change > 0) { + double threshold = AttributeUtil.lookup( + cacheManager, Keys.EVENT_FUEL_INCREASE_THRESHOLD, position.getDeviceId()); + if (change >= threshold) { + return Map.of(new Event(Event.TYPE_DEVICE_FUEL_INCREASE, position), position); + } + } else if (change < 0) { + double threshold = AttributeUtil.lookup( + cacheManager, Keys.EVENT_FUEL_DROP_THRESHOLD, position.getDeviceId()); + if (Math.abs(change) >= threshold) { + return Map.of(new Event(Event.TYPE_DEVICE_FUEL_DROP, position), position); + } } } } diff --git a/src/main/java/org/traccar/model/Event.java b/src/main/java/org/traccar/model/Event.java index f00a0e5f1..0e851d748 100644 --- a/src/main/java/org/traccar/model/Event.java +++ b/src/main/java/org/traccar/model/Event.java @@ -52,6 +52,7 @@ public class Event extends Message { public static final String TYPE_DEVICE_OVERSPEED = "deviceOverspeed"; public static final String TYPE_DEVICE_FUEL_DROP = "deviceFuelDrop"; + public static final String TYPE_DEVICE_FUEL_INCREASE = "deviceFuelIncrease"; public static final String TYPE_GEOFENCE_ENTER = "geofenceEnter"; public static final String TYPE_GEOFENCE_EXIT = "geofenceExit"; diff --git a/templates/full/deviceFuelIncrease.vm b/templates/full/deviceFuelIncrease.vm new file mode 100644 index 000000000..9d4474e1a --- /dev/null +++ b/templates/full/deviceFuelIncrease.vm @@ -0,0 +1,11 @@ +#set($subject = "$device.name: fuel increase") + + + +Device: $device.name
+Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
+Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}
+
+Unsubscribe + + diff --git a/templates/short/deviceFuelIncrease.vm b/templates/short/deviceFuelIncrease.vm new file mode 100644 index 000000000..6a11418b1 --- /dev/null +++ b/templates/short/deviceFuelIncrease.vm @@ -0,0 +1,2 @@ +#set($subject = "$device.name: fuel increase") +$device.name fuel increase at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone) -- cgit v1.2.3 From dbc5fc5dcf697dcc00d357bbca5fe4669325148b Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Sat, 6 Aug 2022 17:42:22 +0100 Subject: Updated Xexun2 Protocol --- src/main/java/org/traccar/helper/Checksum.java | 8 +--- .../org/traccar/protocol/Xexun2FrameEncoder.java | 48 ++++++++++++++++++++++ .../java/org/traccar/protocol/Xexun2Protocol.java | 1 + .../traccar/protocol/Xexun2ProtocolDecoder.java | 12 +++--- .../traccar/protocol/Xexun2ProtocolEncoder.java | 48 ++++------------------ .../traccar/protocol/Xexun2FrameDecoderTest.java | 4 ++ .../traccar/protocol/Xexun2FrameEncoderTest.java | 20 +++++++++ 7 files changed, 90 insertions(+), 51 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java create mode 100644 src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java diff --git a/src/main/java/org/traccar/helper/Checksum.java b/src/main/java/org/traccar/helper/Checksum.java index e660790ef..db5817275 100644 --- a/src/main/java/org/traccar/helper/Checksum.java +++ b/src/main/java/org/traccar/helper/Checksum.java @@ -200,18 +200,14 @@ public final class Checksum { return (10 - (checksum % 10)) % 10; } - public static int udp(ByteBuffer data) { + public static int ip(ByteBuffer data) { int sum = 0; - int len = data.capacity(); - for (int j = 0; len > 1; len--) { + while (data.remaining() > 0) { sum += data.get() & 0xff; if ((sum & 0x80000000) > 0) { sum = (sum & 0xffff) + (sum >> 16); } } - if (len == 1) { - sum += data.get() & 0xff; - } while ((sum >> 16) > 0) { sum = (sum & 0xffff) + sum >> 16; } diff --git a/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java b/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java new file mode 100644 index 000000000..52d43c36c --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2022 Stefan Clark (stefan@stefanclark.co.uk) + * + * 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.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +public class Xexun2FrameEncoder extends MessageToByteEncoder { + + @Override + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) { + out.writeBytes(msg.readBytes(2)); + + while (msg.readableBytes() > 2) { + int b = msg.readUnsignedByte(); + if (b == 0xfa && msg.isReadable() && msg.getUnsignedByte(msg.readerIndex()) == 0xaf) { + msg.readUnsignedByte(); + out.writeByte(0xfb); + out.writeByte(0xbf); + out.writeByte(0x01); + } else if (b == 0xfb && msg.isReadable() && msg.getUnsignedByte(msg.readerIndex()) == 0xbf) { + msg.readUnsignedByte(); + out.writeByte(0xfb); + out.writeByte(0xbf); + out.writeByte(0x02); + } else { + out.writeByte(b); + } + } + + out.writeBytes(msg.readBytes(2)); + + } +} diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index 1d5038a22..52cf731f0 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -35,6 +35,7 @@ public class Xexun2Protocol extends BaseProtocol { addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new Xexun2FrameEncoder()); pipeline.addLast(new Xexun2FrameDecoder()); pipeline.addLast(new Xexun2ProtocolDecoder(Xexun2Protocol.this)); pipeline.addLast(new Xexun2ProtocolEncoder(Xexun2Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index f0158e6ce..913dfaf28 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -42,12 +42,14 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + public static final int FLAG = 0xfaaf; + public static final int MSG_COMMAND = 0x07; public static final int MSG_POSITION = 0x14; private void sendResponse(Channel channel, int type, int index, ByteBuf imei) { if (channel != null) { ByteBuf response = Unpooled.buffer(); - response.writeShort(Xexun2ProtocolEncoder.FLAG); + response.writeShort(FLAG); response.writeShort(type); response.writeShort(index); @@ -56,7 +58,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { response.writeShort(0xfffe); // checksum response.writeByte(1); // response - response.writeShort(Xexun2ProtocolEncoder.FLAG); + response.writeShort(FLAG); channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } @@ -99,13 +101,13 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { } int payloadSize = buf.readUnsignedShort() & 0x03ff; - int checksum = buf.readUnsignedShort(); // checksum + int checksum = buf.readUnsignedShort(); - if (checksum != Checksum.udp(buf.nioBuffer(buf.readerIndex(), payloadSize))) { + if (checksum != Checksum.ip(buf.nioBuffer(buf.readerIndex(), payloadSize))) { return null; } - if (type != Xexun2ProtocolEncoder.MSG_COMMAND) { + if (type != MSG_COMMAND) { sendResponse(channel, type, index, imei); } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index 6e1e1d68d..c315cab30 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -23,61 +23,29 @@ import org.traccar.helper.DataConverter; import org.traccar.model.Command; import org.traccar.Protocol; +import java.nio.charset.StandardCharsets; + public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { public Xexun2ProtocolEncoder(Protocol protocol) { super(protocol); } - public static final int FLAG = 0xfaaf; - public static final int MSG_COMMAND = 0x07; - - private static ByteBuf encodeFrame(ByteBuf buf) { - int bufLength = buf.readableBytes(); - if (bufLength < 5) { - return null; - } - - ByteBuf result = Unpooled.buffer(); - - result.writeBytes(buf.readBytes(2)); - - while (buf.readerIndex() < bufLength - 2) { - int b = buf.readUnsignedByte(); - if (b == 0xfa && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xaf) { - buf.readUnsignedByte(); - result.writeByte(0xfb); - result.writeByte(0xbf); - result.writeByte(0x01); - } else if (b == 0xfb && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xbf) { - buf.readUnsignedByte(); - result.writeByte(0xfb); - result.writeByte(0xbf); - result.writeByte(0x02); - } else { - result.writeByte(b); - } - } - result.writeBytes(buf.readBytes(2)); - - return result; - } - private static ByteBuf encodeContent(String uniqueId, String content) { ByteBuf buf = Unpooled.buffer(); - ByteBuf message = Unpooled.copiedBuffer(content.getBytes()); + ByteBuf message = Unpooled.copiedBuffer(content.getBytes(StandardCharsets.US_ASCII)); - buf.writeShort(FLAG); - buf.writeShort(MSG_COMMAND); + buf.writeShort(Xexun2ProtocolDecoder.FLAG); + buf.writeShort(Xexun2ProtocolDecoder.MSG_COMMAND); buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); buf.writeShort(message.capacity()); - buf.writeShort(Checksum.udp(message.nioBuffer())); + buf.writeShort(Checksum.ip(message.nioBuffer())); buf.writeBytes(message); - buf.writeShort(FLAG); + buf.writeShort(Xexun2ProtocolDecoder.FLAG); - return encodeFrame(buf); + return buf; } @Override diff --git a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java index 7209a423b..34437862c 100644 --- a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java @@ -14,6 +14,10 @@ public class Xexun2FrameDecoderTest extends ProtocolTest { binary("faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf"), decoder.decode(null, null, binary("faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf"))); + verifyFrame( + binary("FAAF123456FAAF123456FBBF123456FAAF"), + decoder.decode(null, null, binary("FAAF123456FBBF01123456FBBF02123456FAAF"))); + } } diff --git a/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java b/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java new file mode 100644 index 000000000..54a8aaa14 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java @@ -0,0 +1,20 @@ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Xexun2FrameEncoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Xexun2FrameEncoder encoder = new Xexun2FrameEncoder(); + + ByteBuf result = Unpooled.buffer(); + encoder.encode(null, binary("FAAF123456FAAF123456FBBF123456FAAF"), result); + verifyFrame(binary("FAAF123456FBBF01123456FBBF02123456FAAF"), result); + } + +} -- cgit v1.2.3 From 890ecacae6a442ae2b8d4a0e0e2acd4f3e052135 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 6 Aug 2022 20:29:27 -0700 Subject: Handle unknown device (fix #4917) --- src/main/java/org/traccar/protocol/WondexProtocolDecoder.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java b/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java index 22d7bade3..46aa65a5d 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WondexProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,6 +74,9 @@ public class WondexProtocolDecoder extends BaseProtocolDecoder { || buf.toString(StandardCharsets.US_ASCII).startsWith("$MSG:")) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -89,12 +92,12 @@ public class WondexProtocolDecoder 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()); position.setTime(parser.nextDateTime()); -- cgit v1.2.3 From 6ea6561d4fab3a04d4fd388c68b8754488f5fe3f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 6 Aug 2022 21:00:43 -0700 Subject: Add integration tests --- tools/test-integration.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/test-integration.py b/tools/test-integration.py index 4a590128f..454585440 100755 --- a/tools/test-integration.py +++ b/tools/test-integration.py @@ -109,6 +109,11 @@ messages = { 'xrb28': '*SCOR,OM,123456789012345,D0,0,012102.00,A,0608.00062,S,10659.70331,E,12,0.69,151118,30.3,M,A#\r\n', 'c2stek': 'PA$123456789012345$D#220222#135059#0#+37.98995#+23.85141#0.00#69.2#0.0#0000#000#8#00#sz-w1001#B2600$AP', 'mictrack': 'MT;6;123456789012345;R0;10+190109091803+22.63827+114.02922+2.14+69+2+3744+113', + 'plugin': '$$STATUS123456,20190528143943,28.254086,-25.860665,0,0,0,-1,2,78,11395,0,0,0#', + 'racedynamics': '$GPRMC,12,260819,100708,123456789012345,\r\n$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\r\n', + 's168': 'S168#123456789012345#0f12#0077#LOCA:G;CELL:1,1cc,2,2795,1435,64;GDATA:A,12,160412154800,22.564025,113.242329,5.5,152,900;ALERT:0000;STATUS:89,98;WAY:0$', + 'dingtek': '800001011e0692001a00000000016e008027c40000112345678901234581', + 'portman': '$PTMLA,123456789012345,A,200612153351,N2543.0681W10009.2974,0,190,NA,C9830000,NA,108,8,2.66,16,GNA\r\n', } baseUrl = 'http://localhost:8082' -- cgit v1.2.3 From 315be9dd7425c36cb612af1155f3195baf06bc6f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 6 Aug 2022 21:00:54 -0700 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 135654c9d..1b1fbb738 100644 --- a/build.gradle +++ b/build.gradle @@ -98,7 +98,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.2", + "Implementation-Version": "5.3", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 7734f3956..3e946e672 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.2 +AppVersion=5.3 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index 77ca20ce2..866ac8a7d 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.2", + "version": "5.3", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", @@ -27,6 +27,10 @@ "url": "https://demo3.traccar.org/api", "description": "Demo Server 3" }, + { + "url": "https://demo4.traccar.org/api", + "description": "Demo Server 4" + }, { "url": "https://server.traccar.org/api", "description": "Subscription Server" -- cgit v1.2.3 From f1cebbcc72359367fc172eb9836339fb33398eb4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 6 Aug 2022 21:09:33 -0700 Subject: Fix alarm template --- templates/full/alarm.vm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/full/alarm.vm b/templates/full/alarm.vm index 5d367dc3a..9fae1f13b 100644 --- a/templates/full/alarm.vm +++ b/templates/full/alarm.vm @@ -3,7 +3,7 @@ Device: $device.name
-Alarm: $position.getString("alarm")
+Alarm: $position.getString("alarm")
Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.eventTime, $locale, $timezone)
Point: #{if}($position.address)$position.address#{else}$position.latitude°, $position.longitude°#{end}

-- cgit v1.2.3 From 18799d894619683cbffbbd140648737abd8b4cc5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 6 Aug 2022 21:47:07 -0700 Subject: Handle API 404 errors --- src/main/java/org/traccar/web/WebServer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 704a4b3cd..62ac338eb 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -106,7 +106,8 @@ public class WebServer implements LifecycleObject { protected void handleErrorPage( HttpServletRequest request, Writer writer, int code, String message) throws IOException { Path index = Paths.get(config.getString(Keys.WEB_PATH), "index.html"); - if (code == HttpStatus.NOT_FOUND_404 && Files.exists(index)) { + if (code == HttpStatus.NOT_FOUND_404 + && !request.getPathInfo().startsWith("/api/") && Files.exists(index)) { writer.write(Files.readString(index)); } else { writer.write("Error" -- cgit v1.2.3 From 9b54131699e61890fe6746b93a9a69a12d655ab5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 7 Aug 2022 07:27:18 -0700 Subject: Try different JDK --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 655d47b80..f23a6d7e2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: working-directory: ./traccar-web - uses: actions/setup-java@v3 with: - distribution: temurin + distribution: corretto java-version: 11 cache: gradle - run: ./gradlew build -- cgit v1.2.3 From 6c0524f0534ccce8ab34a72d52f8f67e84234f01 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 7 Aug 2022 07:37:53 -0700 Subject: Try different JDK --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f23a6d7e2..a11ad2640 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: working-directory: ./traccar-web - uses: actions/setup-java@v3 with: - distribution: corretto + distribution: zulu java-version: 11 cache: gradle - run: ./gradlew build -- cgit v1.2.3 From 6685e71d10a6e4243cc987781944aa96fa271618 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 7 Aug 2022 07:52:45 -0700 Subject: Select specific version --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a11ad2640..b63394ca5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,8 +21,8 @@ jobs: working-directory: ./traccar-web - uses: actions/setup-java@v3 with: - distribution: zulu - java-version: 11 + distribution: temurin + java-version: 11.0.15 cache: gradle - run: ./gradlew build - uses: actions/setup-node@v3 -- cgit v1.2.3 From 5b75c4a847dd768a1e75353021940ce3ffb896df Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 7 Aug 2022 09:46:36 -0700 Subject: Remove field --- swagger.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/swagger.json b/swagger.json index 866ac8a7d..acdc1053a 100644 --- a/swagger.json +++ b/swagger.json @@ -2718,9 +2718,6 @@ "poiLayer": { "type": "string" }, - "token": { - "type": "string" - }, "attributes": { "type": "object", "properties": {} -- cgit v1.2.3 From 803e8d24d46b99b24fcf76c6b5ea687accd4a4d1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 7 Aug 2022 10:08:19 -0700 Subject: Update submodule commit --- traccar-web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traccar-web b/traccar-web index 33f9da8e9..980956695 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit 33f9da8e98763416d7f440e7ac4b8177c929eaff +Subproject commit 980956695258be1ff464923c76c1c6db1df397c1 -- cgit v1.2.3 From eaa390e74ead87dc953a3af9dd22ee68b35d8a59 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 8 Aug 2022 08:23:50 -0700 Subject: Drop token index (fix #4918) --- schema/changelog-5.3.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/schema/changelog-5.3.xml b/schema/changelog-5.3.xml index 3b103a6fa..2021fe6c7 100644 --- a/schema/changelog-5.3.xml +++ b/schema/changelog-5.3.xml @@ -32,6 +32,8 @@
+ + -- cgit v1.2.3 From a551ac40761520e8d48e4438213f70854569c1d9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 8 Aug 2022 16:53:12 -0700 Subject: Fix Iridium decoding --- src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index b1deded3b..1f6a4d2b4 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -262,7 +262,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(4); // reserved position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - buf.skipBytes(3); // coordinates header + buf.skipBytes(2); // coordinates header int flags = buf.readUnsignedByte(); double latitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; double longitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; -- cgit v1.2.3 From 8fb2596c60d8e63e9933de4b077253f14daa1472 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 8 Aug 2022 17:47:25 -0700 Subject: Implement BSTPL protocol --- setup/default.xml | 1 + .../java/org/traccar/protocol/BstplProtocol.java | 43 +++++++ .../org/traccar/protocol/BstplProtocolDecoder.java | 137 +++++++++++++++++++++ .../traccar/protocol/BstplProtocolDecoderTest.java | 21 ++++ 4 files changed, 202 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/BstplProtocol.java create mode 100644 src/main/java/org/traccar/protocol/BstplProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/BstplProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 0abc96431..607efc35f 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -283,5 +283,6 @@ 5238 5239 5240 + 5241 diff --git a/src/main/java/org/traccar/protocol/BstplProtocol.java b/src/main/java/org/traccar/protocol/BstplProtocol.java new file mode 100644 index 000000000..dde14a2ca --- /dev/null +++ b/src/main/java/org/traccar/protocol/BstplProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class BstplProtocol extends BaseProtocol { + + @Inject + public BstplProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#')); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new BstplProtocolDecoder(BstplProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java b/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java new file mode 100644 index 000000000..15c114642 --- /dev/null +++ b/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java @@ -0,0 +1,137 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.Protocol; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class BstplProtocolDecoder extends BaseProtocolDecoder { + + public BstplProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("BSTPL$") // header + .number("(d),") // type + .expression("([^,]+),") // device id + .expression("([AV]),") // validity + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(d+.d+),([0NS]),") // latitude + .number("(d+.d+),([0EW]),") // longitude + .number("(d+),") // speed + .number("(d+),") // odometer + .number("(d+),") // course + .number("(d+),") // satellites + .number("([01]),") // box open + .number("(d+),") // rssi + .number("([01]),") // charge + .number("([01]),") // ignition + .number("([01]),") // engine + .number("([01]),") // locked + .number("(d+.d+),") // adc + .number("d+,") // reserved + .number("(d+.d+),") // battery + .expression("([^,]+),") // firmware + .number("([^,]+),") // iccid + .number("(d+.d+)") // power + .compile(); + + private String decodeAlarm(int value) { + switch (value) { + case 4: + return Position.ALARM_LOW_BATTERY; + case 5: + return Position.ALARM_ACCELERATION; + case 6: + return Position.ALARM_BRAKING; + case 7: + return Position.ALARM_OVERSPEED; + case 9: + return Position.ALARM_SOS; + default: + return null; + } + } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + int type = parser.nextInt(); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_ALARM, decodeAlarm(type)); + + position.setValid(parser.next().equals("A")); + 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.nextInt())); + + position.set(Position.KEY_ODOMETER, parser.nextInt() * 1000L); + + position.setCourse(parser.nextInt()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + + boolean boxOpen = parser.nextInt() > 0; + if (type == 8 && boxOpen) { + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + } + position.set("boxOpen", boxOpen); + + position.set(Position.KEY_RSSI, parser.nextInt()); + + boolean charge = parser.nextInt() > 0; + if (type == 3) { + position.set(Position.KEY_ALARM, charge ? Position.ALARM_POWER_RESTORED : Position.ALARM_POWER_CUT); + } + position.set(Position.KEY_CHARGE, charge); + + position.set(Position.KEY_IGNITION, parser.nextInt() > 0); + position.set("engine", parser.nextInt() > 0); + position.set(Position.KEY_BLOCKED, parser.nextInt() > 0); + position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + position.set(Position.KEY_ICCID, parser.next()); + position.set(Position.KEY_POWER, parser.nextDouble()); + + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/BstplProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BstplProtocolDecoderTest.java new file mode 100644 index 000000000..ae4c47229 --- /dev/null +++ b/src/test/java/org/traccar/protocol/BstplProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class BstplProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new BstplProtocolDecoder(null)); + + verifyPosition(decoder, text( + "BSTPL$1,869630054439504,V,200722,045113,00.000000,0,00.00000,0,0,0,000,00,0,17,1,1,0,0,00.01,0,04.19,15B_190821,8991000907387031196F,12.27")); + + verifyPosition(decoder, text( + "BSTPL$1,AP12AP3456,A,130720,160552,27.244183,N,83.673973,E,20,156,183,17,0,11,1,0,0,0,00.00,00,04.16,15_V1_0_0,89917380578146790443,12.16")); + + } + +} -- cgit v1.2.3 From 90a6ae2affe642ced72a6a47fa0e0f919cbaeba3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 8 Aug 2022 17:51:53 -0700 Subject: Remove empty comment lines --- src/main/java/org/traccar/config/Keys.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index a3b39581d..e6c3656da 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1168,7 +1168,6 @@ public final class Keys { * Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if Position * appears valid or if Position `speed` field reported by the device is also within limits. Calculates speed from * the distance to the previous position and the elapsed time. - * * Tip: Shouldn't be too low. Start testing with values at about 25000. */ public static final ConfigKey FILTER_MAX_SPEED = new IntegerConfigKey( @@ -1185,7 +1184,6 @@ public final class Keys { /** * If false, the server expects all locations to come sequentially (for each device). Filter checks for duplicates, * distance, speed, or time period only against the location that was last received by server. - * * If true, the server expects locations to come at random order (since tracking device might go offline). * Filter checks for duplicates, distance, speed, or time period against the preceding Position's. * Important: setting to true can cause potential performance issues. @@ -1229,7 +1227,6 @@ public final class Keys { /** * List of protocols to enable. If not specified, Traccar enabled all protocols that have port numbers listed. * The value is a comma-separated list of protocol names. - * * Example value: teltonika,osmand */ public static final ConfigKey PROTOCOLS_ENABLE = new StringConfigKey( @@ -1522,7 +1519,6 @@ public final class Keys { /** * Public URL for the web app. Used for notification and report link. - * * If not provided, Traccar will attempt to get a URL from the server IP address, but it might be a local address. */ public static final ConfigKey WEB_URL = new StringConfigKey( -- cgit v1.2.3 From 48a703302a8213402d5225d0087abc13521410a3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 8 Aug 2022 18:30:56 -0700 Subject: Remove trailing URL slash --- src/main/java/org/traccar/MainModule.java | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index b8ff21472..e0617a734 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -318,17 +318,19 @@ public class MainModule extends AbstractModule { properties.setProperty("file.resource.loader.path", config.getString(Keys.TEMPLATES_ROOT) + "/"); properties.setProperty("runtime.log.logsystem.class", NullLogChute.class.getName()); - String address; - try { - address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); - } catch (UnknownHostException e) { - address = "localhost"; + if (config.hasKey(Keys.WEB_URL)) { + properties.setProperty("web.url", config.getString(Keys.WEB_URL).replaceAll("/$", "")); + } else { + String address; + try { + address = config.getString(Keys.WEB_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (UnknownHostException e) { + address = "localhost"; + } + String url = URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", ""); + properties.setProperty("web.url", url); } - String url = config.getString( - Keys.WEB_URL, URIUtil.newURI("http", address, config.getInteger(Keys.WEB_PORT), "", "")); - properties.setProperty("web.url", url); - VelocityEngine velocityEngine = new VelocityEngine(); velocityEngine.init(properties); return velocityEngine; -- cgit v1.2.3 From afe2ff412a22e265a29e5ac151355eba429b304e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 Aug 2022 10:04:41 -0700 Subject: Checkout full history --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b63394ca5..5a4465415 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,6 +16,7 @@ jobs: steps: - uses: actions/checkout@v3 with: + fetch-depth: 0 submodules: true - run: git checkout ${{ github.ref_name }} working-directory: ./traccar-web -- cgit v1.2.3 From 596315224144c78bff043a3e3a67b005ec0a0e30 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 Aug 2022 16:42:11 -0700 Subject: Update package script --- setup/package.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/setup/package.sh b/setup/package.sh index 40dac475d..3cfe88a52 100755 --- a/setup/package.sh +++ b/setup/package.sh @@ -61,17 +61,17 @@ fi if [ $PLATFORM = "all" -o $PLATFORM = "windows-64" ]; then check_requirement "Inno Extractor" "which innoextract" "Missing innoextract binary" check_requirement "Inno Setup" "ls i*setup-*.exe" "Missing Inno Setup (http://www.jrsoftware.org/isdl.php)" - check_requirement "Windows 64 Java" "ls java-*.windows.ojdkbuild.x86_64.zip" "Missing Windows 64 Java (https://github.com/ojdkbuild/ojdkbuild)" + check_requirement "Windows 64 Java" "ls OpenJDK*x64_windows*.zip" "Missing Windows 64 JDK (https://adoptium.net/)" check_requirement "Wine" "which wine" "Missing wine binary" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" -o $PLATFORM = "linux-arm" ]; then check_requirement "Makeself" "which makeself" "Missing makeself binary" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" ]; then - check_requirement "Linux 64 Java" "ls jdk-*-linux-x64.zip" "Missing Linux 64 Java (https://github.com/ojdkbuild/contrib_jdk11u-ci/releases)" + check_requirement "Linux 64 Java" "ls OpenJDK*x64_linux*.tar.gz" "Missing Linux 64 JDK (https://adoptium.net/)" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-arm" ]; then - check_requirement "Linux ARM Java" "ls jdk-*-linux-armhf.zip" "Missing Linux ARM Java (https://github.com/ojdkbuild/contrib_jdk11u-aarch32-ci/releases)" + check_requirement "Linux ARM Java" "ls OpenJDK*arm_linux*.tar.gz" "Missing Linux ARM JDK (https://adoptium.net/)" fi if [ $PREREQ = false ]; then info "Missing build requirements, aborting..." @@ -119,9 +119,9 @@ package_other () { package_windows () { info "Building Windows 64 installer" - unzip -q -o java-*.windows.ojdkbuild.x86_64.zip - jlink --module-path java-*.windows.ojdkbuild.x86_64/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre - rm -rf java-*.windows.ojdkbuild.x86_64 + unzip -q OpenJDK*x64_windows*.zip + jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre + rm -rf jdk-* wine app/ISCC.exe traccar.iss >/dev/null rm -rf out/jre zip -q -j traccar-windows-64-$VERSION.zip Output/traccar-setup.exe README.txt @@ -133,13 +133,13 @@ package_linux () { cp setup.sh out cp traccar.service out - unzip -q -o jdk-*-linux-$1.zip - jlink --module-path jdk-*-linux-$1/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre - rm -rf jdk-*-linux-$1 + tar -xf OpenJDK*$1_linux*.tar.gz + jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre + rm -rf jdk-* makeself --needroot --quiet --notemp out traccar.run "traccar" ./setup.sh rm -rf out/jre - zip -q -j traccar-linux-$2-$VERSION.zip traccar.run README.txt + zip -q -j traccar-linux-$1-$VERSION.zip traccar.run README.txt rm traccar.run rm out/setup.sh @@ -148,13 +148,13 @@ package_linux () { package_linux_64 () { info "Building Linux 64 installer" - package_linux x64 64 + package_linux x64 ok "Created Linux 64 installer" } package_linux_arm () { info "Building Linux ARM installer" - package_linux armhf arm + package_linux arm ok "Created Linux ARM installer" } -- cgit v1.2.3 From d5bb27d42a6d1e5c9fc9e6fe1c777383050c5e28 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 Aug 2022 16:43:52 -0700 Subject: Update release action --- .github/workflows/release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5a4465415..4ceb88a7c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/setup-java@v3 with: distribution: temurin - java-version: 11.0.15 + java-version: 17 cache: gradle - run: ./gradlew build - uses: actions/setup-node@v3 @@ -47,9 +47,9 @@ jobs: working-directory: ./setup run: | wget -q http://files.jrsoftware.org/is/5/isetup-5.5.6.exe - wget -q https://github.com/ojdkbuild/ojdkbuild/releases/download/java-11-openjdk-11.0.15.9-1/java-11-openjdk-11.0.15.9-1.windows.ojdkbuild.x86_64.zip - wget -q https://github.com/ojdkbuild/contrib_jdk11u-ci/releases/download/jdk-11.0.15%2B10/jdk-11.0.15-ojdkbuild-linux-x64.zip - wget -q https://github.com/ojdkbuild/contrib_jdk11u-arm32-ci/releases/download/jdk-11.0.15%2B10/jdk-11.0.15-ojdkbuild-linux-armhf.zip + wget -q https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.4+8/OpenJDK17U-jdk_x64_windows_hotspot_17.0.4_8.zip + wget -q https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.4+8/OpenJDK17U-jdk_x64_linux_hotspot_17.0.4_8.tar.gz + wget -q https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.4+8/OpenJDK17U-jdk_arm_linux_hotspot_17.0.4_8.tar.gz ./package.sh ${{ github.event.inputs.version }} - name: Upload installers working-directory: ./setup -- cgit v1.2.3 From 4f60122750cc61b5f2112a285036a98957b8273b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 9 Aug 2022 17:16:11 -0700 Subject: Fix linux package name --- setup/package.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/package.sh b/setup/package.sh index 3cfe88a52..71b86014f 100755 --- a/setup/package.sh +++ b/setup/package.sh @@ -61,14 +61,14 @@ fi if [ $PLATFORM = "all" -o $PLATFORM = "windows-64" ]; then check_requirement "Inno Extractor" "which innoextract" "Missing innoextract binary" check_requirement "Inno Setup" "ls i*setup-*.exe" "Missing Inno Setup (http://www.jrsoftware.org/isdl.php)" - check_requirement "Windows 64 Java" "ls OpenJDK*x64_windows*.zip" "Missing Windows 64 JDK (https://adoptium.net/)" + check_requirement "Windows 64 Java" "ls OpenJDK*64_windows*.zip" "Missing Windows 64 JDK (https://adoptium.net/)" check_requirement "Wine" "which wine" "Missing wine binary" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" -o $PLATFORM = "linux-arm" ]; then check_requirement "Makeself" "which makeself" "Missing makeself binary" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-64" ]; then - check_requirement "Linux 64 Java" "ls OpenJDK*x64_linux*.tar.gz" "Missing Linux 64 JDK (https://adoptium.net/)" + check_requirement "Linux 64 Java" "ls OpenJDK*64_linux*.tar.gz" "Missing Linux 64 JDK (https://adoptium.net/)" fi if [ $PLATFORM = "all" -o $PLATFORM = "linux-arm" ]; then check_requirement "Linux ARM Java" "ls OpenJDK*arm_linux*.tar.gz" "Missing Linux ARM JDK (https://adoptium.net/)" @@ -119,7 +119,7 @@ package_other () { package_windows () { info "Building Windows 64 installer" - unzip -q OpenJDK*x64_windows*.zip + unzip -q OpenJDK*64_windows*.zip jlink --module-path jdk-*/jmods --add-modules java.se,jdk.charsets,jdk.crypto.ec --output out/jre rm -rf jdk-* wine app/ISCC.exe traccar.iss >/dev/null @@ -148,7 +148,7 @@ package_linux () { package_linux_64 () { info "Building Linux 64 installer" - package_linux x64 + package_linux 64 ok "Created Linux 64 installer" } -- cgit v1.2.3 From d8607eb0e840df9df7006f7ae2a15b8b082bf7bf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 12 Aug 2022 17:07:31 -0700 Subject: Support Suntech ignition --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index 52fdaa05c..f1097abac 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -570,7 +570,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(mask, 17)) { - position.set(Position.KEY_INPUT, Integer.parseInt(values[index++])); + int input = Integer.parseInt(values[index++]); + position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); + position.set(Position.KEY_INPUT, input); } if (BitUtil.check(mask, 18)) { -- cgit v1.2.3 From 8cb215e3426f948802f82cbd22dfddcac45d5ef0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 12 Aug 2022 17:11:56 -0700 Subject: Use GT06 declared types --- src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index e1c17710b..6b2cd6833 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java @@ -44,7 +44,7 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { buf.writeByte(1 + 1 + 4 + content.length() + 2 + 2 + (language ? 2 : 0)); // message length - buf.writeByte(0x80); // message type + buf.writeByte(Gt06ProtocolDecoder.MSG_COMMAND_0); buf.writeByte(4 + content.length()); // command length buf.writeInt(0); -- cgit v1.2.3 From 8a7275a8680ca0db4def3b4c52ad1ddcf4525949 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 12 Aug 2022 17:37:08 -0700 Subject: Handle calendar caching --- .../org/traccar/session/cache/CacheManager.java | 41 ++++++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 07f27d776..6f6b648fa 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -20,6 +20,7 @@ import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; +import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -28,6 +29,7 @@ import org.traccar.model.GroupedModel; import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.Position; +import org.traccar.model.ScheduledModel; import org.traccar.model.Server; import org.traccar.model.User; import org.traccar.storage.Storage; @@ -218,6 +220,10 @@ public class CacheManager implements BroadcastInterface { if (((GroupedModel) before).getGroupId() != ((GroupedModel) object).getGroupId()) { invalidate = true; } + } else if (object instanceof ScheduledModel) { + if (((ScheduledModel) before).getCalendarId() != ((ScheduledModel) object).getCalendarId()) { + invalidate = true; + } } if (invalidate) { invalidate(object.getClass(), object.getId()); @@ -294,7 +300,19 @@ public class CacheManager implements BroadcastInterface { var objects = storage.getObjects(clazz, new Request( new Columns.All(), new Condition.Permission(Device.class, deviceId, clazz))); links.put(clazz, objects.stream().map(BaseModel::getId).collect(Collectors.toSet())); - objects.forEach(object -> addObject(deviceId, object)); + for (var object : objects) { + addObject(deviceId, object); + if (object instanceof ScheduledModel) { + var scheduled = (ScheduledModel) object; + if (scheduled.getCalendarId() > 0) { + var calendar = storage.getObject(Calendar.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", scheduled.getCalendarId()))); + links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) + .add(calendar.getId()); + addObject(deviceId, calendar); + } + } + } } var users = storage.getObjects(User.class, new Request( @@ -303,13 +321,22 @@ public class CacheManager implements BroadcastInterface { for (var user : users) { addObject(deviceId, user); var notifications = storage.getObjects(Notification.class, new Request( - new Columns.All(), new Condition.Permission(User.class, user.getId(), Notification.class))); - notifications.stream() + new Columns.All(), + new Condition.Permission(User.class, user.getId(), Notification.class))).stream() .filter(Notification::getAlways) - .forEach(object -> { - links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()).add(object.getId()); - addObject(deviceId, object); - }); + .collect(Collectors.toList()); + for (var notification : notifications) { + links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) + .add(notification.getId()); + addObject(deviceId, notification); + if (notification.getCalendarId() > 0) { + var calendar = storage.getObject(Calendar.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", notification.getCalendarId()))); + links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) + .add(calendar.getId()); + addObject(deviceId, calendar); + } + } } deviceLinks.put(deviceId, links); -- cgit v1.2.3 From 7237e4b515884721058993f2ccb8f06f8333b867 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 12 Aug 2022 17:38:18 -0700 Subject: Support OsmAnd charging info --- src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java index 5f8e7424b..c8968023a 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -143,6 +143,9 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { case "driverUniqueId": position.set(Position.KEY_DRIVER_UNIQUE_ID, value); break; + case "charge": + position.set(Position.KEY_CHARGE, Boolean.parseBoolean(value)); + break; default: try { position.set(entry.getKey(), Double.parseDouble(value)); -- cgit v1.2.3 From 10aba298620884d6f018fe94cda9b1d4d4a9e20f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 13 Aug 2022 06:44:32 -0700 Subject: Fix deprecated --- src/main/java/org/traccar/protocol/IotmProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java index 57e4c736f..bdc691d27 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -339,7 +339,7 @@ public class IotmProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // checksum MqttMessage response = MqttMessageBuilders.pubAck() - .packetId((short) message.variableHeader().packetId()) + .packetId(message.variableHeader().packetId()) .build(); if (channel != null) { -- cgit v1.2.3 From 812994893d2bdd3e873b1ba27844b713f59e5449 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 13 Aug 2022 06:44:59 -0700 Subject: Fix deprecated --- src/main/java/org/traccar/protocol/IotmProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java index bdc691d27..7bbe6c8de 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java @@ -260,7 +260,7 @@ public class IotmProtocolDecoder extends BaseProtocolDecoder { MqttSubscribeMessage message = (MqttSubscribeMessage) msg; MqttMessage response = MqttMessageBuilders.subAck() - .packetId((short) message.variableHeader().messageId()) + .packetId(message.variableHeader().messageId()) .build(); if (channel != null) { -- cgit v1.2.3 From d16c01cbefd634e285354bc4a097736644332eba Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 14 Aug 2022 06:47:32 -0700 Subject: Fix FM11 FM12 FM36 decoding --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 2b1196d55..2476fd384 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -253,8 +253,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(182, null, (p, b) -> p.set(Position.KEY_HDOP, b.readUnsignedShort() * 0.1)); register(199, null, (p, b) -> p.set(Position.KEY_ODOMETER_TRIP, b.readUnsignedInt())); register(200, fmbXXX, (p, b) -> p.set("sleepMode", b.readUnsignedByte())); - register(205, null, (p, b) -> p.set("cid", b.readUnsignedShort())); - register(206, null, (p, b) -> p.set("lac", b.readUnsignedShort())); + register(205, fmbXXX, (p, b) -> p.set("cid", b.readUnsignedShort())); + register(206, fmbXXX, (p, b) -> p.set("lac", b.readUnsignedShort())); register(236, null, (p, b) -> { p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_GENERAL : null); }); diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 0ae4bbfa4..6a13f59c9 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, binary( + "00000000000000e708030000018293d62060000de1f6a62159767e00000000000000000b074504f00050041500c801ef004f630342320043000344000001f100006019000000018291b0c790000de1f6a62159767e006e0144070000ef12074503f00050051505c800ef004f0207b5000eb6000b423324180000ce00dc43001144000004c700000007f100006019cd0003c7776300ea4e2e000000018291aff0b8000de1f91f21597405006f00f61300080012074503f00150051504c800ef014f0207b50009b600054236c1180008ce00dc43003f44000004c700000003f100006019cd0003c7776300ea4e2700030000a48d")); + verifyPositions(decoder, binary( "00000000000000da08030000017fcedf499600280431be0eded45d0038012d100000fa100901000200b300b4004501500415034702fa00054232a1180000cd3b2fce281d43001f02c700000006f10000a029000000017fcedea99600280432070eded3dd00380046130009000f0801010200b300b400450150051502470205423276180009cd3b2fce281d43001f02c700000027f10000a0290000000179d50853180027f65d3f0ed67212001500f1110061000f0801010200b300b4004501500515034702054234f4180061cd53d1ce28c043003e02c700000147f1000000290003000052cb")); -- cgit v1.2.3 From 74a6ec5ff14e4871a0f61d05aa4cec89d0950038 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 16 Aug 2022 07:54:54 -0700 Subject: Fix FM6320 decoding --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 2476fd384..89124cb22 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -244,7 +244,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { p.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId)); } }); - register(80, null, (p, b) -> p.set("dataMode", b.readUnsignedByte())); + register(80, fmbXXX, (p, b) -> p.set("dataMode", b.readUnsignedByte())); register(90, null, (p, b) -> p.set(Position.KEY_DOOR, b.readUnsignedShort())); register(115, fmbXXX, (p, b) -> p.set(Position.KEY_COOLANT_TEMP, b.readShort() * 0.1)); register(179, null, (p, b) -> p.set(Position.PREFIX_OUT + 1, b.readUnsignedByte() > 0)); diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 6a13f59c9..994a55109 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, binary( + "00000000000003831004000001735ace37f80000e3b9331c71e290006900e211005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005538006e00006f00007a03007d00007f5600890000fd0200fe1f09004326b00044000000b5000b00b6000600427029001800540046015d00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022a1005000000054005400000000005600015568005700000060005800000420006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3ca80000e3b08a1c71dd29006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0200fe1d09004326ac0044000000b5000b00b600060042701f001800540046015d00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022ce00500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3fc80000e3a7c01c71d7c2006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0200fe2309004326ac0044000000b5000b00b6000600427015001800540046015e00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022e700500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3ffa0000e3a7c01c71d7c2006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0300fe2309004326ac0044000000b5000b00b6000600427015001800540046015e00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022e700500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000040000eb85")); + verifyPositions(decoder, binary( "00000000000000e708030000018293d62060000de1f6a62159767e00000000000000000b074504f00050041500c801ef004f630342320043000344000001f100006019000000018291b0c790000de1f6a62159767e006e0144070000ef12074503f00050051505c800ef004f0207b5000eb6000b423324180000ce00dc43001144000004c700000007f100006019cd0003c7776300ea4e2e000000018291aff0b8000de1f91f21597405006f00f61300080012074503f00150051504c800ef014f0207b50009b600054236c1180008ce00dc43003f44000004c700000003f100006019cd0003c7776300ea4e2700030000a48d")); -- cgit v1.2.3 From 18addfa5b5535dbf8d48c7bbfd01c7234e0154bf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 16 Aug 2022 14:38:17 -0700 Subject: Change ignition test --- tools/test-generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/test-generator.py b/tools/test-generator.py index eb50d2600..d49b98744 100755 --- a/tools/test-generator.py +++ b/tools/test-generator.py @@ -74,7 +74,7 @@ while True: speed = device_speed if (index % len(points)) != 0 else 0 alarm = (index % 10) == 0 battery = random.randint(0, 100) - ignition = (index % len(points)) != 0 + ignition = (index / 10 % 2) != 0 accuracy = 100 if (index % 10) == 0 else 0 rpm = random.randint(500, 4000) fuel = random.randint(0, 80) -- cgit v1.2.3 From a0e484704bd9b5e046a6940beb7450168b5188df Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 16 Aug 2022 17:39:55 -0700 Subject: Decode minimal data set --- .../traccar/protocol/GalileoProtocolDecoder.java | 42 ++++++++++++++++------ 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index 1f6a4d2b4..fc8a49cf5 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -20,15 +20,16 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.helper.BitUtil; -import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; +import org.traccar.helper.BitBuffer; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; +import org.traccar.session.DeviceSession; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -36,6 +37,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TimeZone; public class GalileoProtocolDecoder extends BaseProtocolDecoder { @@ -242,6 +244,27 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { return null; } + private void decodeMinimalDataSet(Position position, ByteBuf buf) { + BitBuffer bits = new BitBuffer(buf.readSlice(10)); + bits.readUnsigned(1); + + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.set(Calendar.DAY_OF_YEAR, 1); + calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY)); + calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE)); + calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND)); + calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); + calendar.add(Calendar.SECOND, bits.readUnsigned(25)); + position.setTime(calendar.getTime()); + + position.setValid(bits.readUnsigned(1) == 0); + position.setLongitude(360 * bits.readUnsigned(22) / 4194304.0 - 180); + position.setLatitude(360 * bits.readUnsigned(21) / 2097152.0 - 90); + if (bits.readUnsigned(1) > 0) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + } + private Position decodeIridiumPosition(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.readUnsignedShortLE(); // length @@ -260,15 +283,12 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // session status buf.skipBytes(4); // reserved - position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - - buf.skipBytes(2); // coordinates header - int flags = buf.readUnsignedByte(); - double latitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; - double longitude = buf.readUnsignedByte() + buf.readUnsignedShortLE() / 60000.0; - position.setLatitude(BitUtil.check(flags, 1) ? -latitude : latitude); - position.setLongitude(BitUtil.check(flags, 0) ? -longitude : longitude); - position.setAccuracy(buf.readUnsignedIntLE()); + buf.readUnsignedIntLE(); // date and time + + buf.skipBytes(23); // coordinates block + + buf.skipBytes(3); // data tag header + decodeMinimalDataSet(position, buf); return position; } -- cgit v1.2.3 From d11002c4820c2f964a9e4c2f1bdc8b758bfa7050 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 16 Aug 2022 17:59:38 -0700 Subject: Add Mobicom driving behavior --- .../traccar/protocol/HuabaoProtocolDecoder.java | 38 +++++++++++++++++++++- .../protocol/HuabaoProtocolDecoderTest.java | 4 +++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index b891bc388..5393c6f74 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -490,7 +490,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); break; case 0xD4: - case 0xFE: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; case 0xD5: @@ -561,6 +560,43 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; + case 0xFE: + if (length == 1) { + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } else { + int mark = buf.readUnsignedByte(); + if (mark == 0x7C) { + while (buf.readerIndex() < endIndex) { + int extendedType = buf.readUnsignedByte(); + int extendedLength = buf.readUnsignedByte(); + switch (extendedType) { + case 0x01: + long alarms = buf.readUnsignedInt(); + if (BitUtil.check(alarms, 0)) { + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + } + if (BitUtil.check(alarms, 1)) { + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + } + if (BitUtil.check(alarms, 2)) { + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + } + if (BitUtil.check(alarms, 3)) { + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + } + if (BitUtil.check(alarms, 4)) { + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + } + break; + default: + buf.skipBytes(extendedLength); + break; + } + } + } + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } + break; default: break; } diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 49622745f..7322185d5 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "7E0200008201215233475100030000000000000003015A7F6106CF8CEC003D0000000021071311481901040000005630011931011AE10200755D3D0601CC0024990A7dA0032301CC002499099B2941FC01CC002499099B29430B01CC0024990A7dA0290601CC0024990A7dA015FD01CC0026220994506BFFFE157C010400000001F10C000000000000000000000000997E"), + Position.KEY_ALARM, Position.ALARM_ACCELERATION); + verifyAttribute(decoder, binary( "7e020000340551231425560568000000000400000201618a9706c320e100410000002722060816261501040000015d300115310105eb0a000300e164000300e301957e"), Position.KEY_BATTERY_LEVEL, 100); -- cgit v1.2.3 From 6bce58763ef9b8ba3b75139114f727c5685694d0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 17 Aug 2022 06:29:07 -0700 Subject: Correct G109 command format --- .../org/traccar/protocol/Gt06ProtocolEncoder.java | 23 +++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java index 6b2cd6833..dc5dd446f 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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.config.Keys; import org.traccar.helper.Checksum; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; +import org.traccar.model.Device; import java.nio.charset.StandardCharsets; @@ -73,13 +74,25 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder { String password = AttributeUtil.getDevicePassword( getCacheManager(), command.getDeviceId(), getProtocolName(), "123456"); + Device device = getCacheManager().getObject(Device.class, command.getDeviceId()); + switch (command.getType()) { case Command.TYPE_ENGINE_STOP: - return encodeContent(command.getDeviceId(), - alternative ? "DYD," + password + "#" : "Relay,1#"); + if ("G109".equals(device.getModel())) { + return encodeContent(command.getDeviceId(), "DYD#"); + } else if (alternative) { + return encodeContent(command.getDeviceId(), "DYD," + password + "#"); + } else { + return encodeContent(command.getDeviceId(), "Relay,1#"); + } case Command.TYPE_ENGINE_RESUME: - return encodeContent(command.getDeviceId(), - alternative ? "HFYD," + password + "#" : "Relay,0#"); + if ("G109".equals(device.getModel())) { + return encodeContent(command.getDeviceId(), "HFYD#"); + } else if (alternative) { + return encodeContent(command.getDeviceId(), "HFYD," + password + "#"); + } else { + return encodeContent(command.getDeviceId(), "Relay,0#"); + } case Command.TYPE_CUSTOM: return encodeContent(command.getDeviceId(), command.getString(Command.KEY_DATA)); default: -- cgit v1.2.3 From 3899dddebcee96b80d5c939f50b846ef5042a7ff Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 18 Aug 2022 16:22:42 -0700 Subject: Firebase include event id --- src/main/java/org/traccar/notificators/NotificatorFirebase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index ecf3fbb70..6510963c7 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -80,6 +80,7 @@ public class NotificatorFirebase implements Notificator { .build()) .build()) .addAllTokens(registrationTokens) + .putData("eventId", String.valueOf(event.getId())) .build(); try { -- cgit v1.2.3 From 1fb6c86ea12f325bfdb372d98400c8a904c6e927 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 20 Aug 2022 09:00:27 -0700 Subject: Support TK103 cell info (fix #4925) --- src/main/java/org/traccar/helper/PatternUtil.java | 2 +- .../org/traccar/protocol/Tk103ProtocolDecoder.java | 49 +++++++++++++++++++++- .../traccar/protocol/Tk103ProtocolDecoderTest.java | 6 +++ 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/helper/PatternUtil.java b/src/main/java/org/traccar/helper/PatternUtil.java index 74813e1d9..a46c7b7b4 100644 --- a/src/main/java/org/traccar/helper/PatternUtil.java +++ b/src/main/java/org/traccar/helper/PatternUtil.java @@ -63,7 +63,7 @@ public final class PatternUtil { for (int i = 0; i < pattern.length(); i++) { try { - Matcher matcher = Pattern.compile("(" + pattern.substring(0, i) + ").*").matcher(input); + Matcher matcher = Pattern.compile("(" + pattern.substring(0, i) + ")[\\s\\S]*").matcher(input); if (matcher.matches()) { result.patternMatch = pattern.substring(0, i); result.patternTail = pattern.substring(i); diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java index e197a8a41..b343c3b33 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,6 +99,16 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); + private static final Pattern PATTERN_CELL = new PatternBuilder() + .text("(") + .number("(d{12})") // device id + .expression(".{4}") // type + .number("(?:d{15})?,") // imei + .expression("(.+),") // cell + .number("(d{8})") // odometer + .text(")") + .compile(); + private static final Pattern PATTERN_NETWORK = new PatternBuilder() .text("(").optional() .number("(d{12})") // device id @@ -297,6 +307,39 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeCell(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_CELL, 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); + + Network network = new Network(); + + String[] cells = parser.next().split("\n"); + for (String cell : cells) { + String[] values = cell.substring(1, cell.length() - 1).split(","); + network.addCellTower(CellTower.from( + Integer.parseInt(values[0]), Integer.parseInt(values[1]), + Integer.parseInt(values[2]), Integer.parseInt(values[3]))); + } + + position.setNetwork(network); + + position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0)); + + return position; + } + private Position decodeNetwork(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_NETWORK, sentence); if (!parser.matches()) { @@ -422,7 +465,9 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { } } - if (sentence.contains("ZC20")) { + if (sentence.indexOf('{') > 0 && sentence.indexOf('}') > 0) { + return decodeCell(channel, remoteAddress, sentence); + } else if (sentence.contains("ZC20")) { return decodeBattery(channel, remoteAddress, sentence); } else if (sentence.contains("BZ00")) { return decodeNetwork(channel, remoteAddress, sentence); diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java index 6c01c14f7..8b3177136 100644 --- a/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tk103ProtocolDecoderTest.java @@ -11,6 +11,12 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Tk103ProtocolDecoder(null)); + verifyAttributes(decoder, text( + "(027046434858BZ00,{460,0,20949,58711}\n{460,0,20494,54003}\n{460,0,20951,19569}\n,01000000)")); + + verifyAttributes(decoder, text( + "(027045009305BP05355227045009305,{413,2,30073,16724}\n{413,2,30073,16730}\n{413,2,30073,49860}\n,01000000)")); + verifyPosition(decoder, text( "(868822040452227,DW3B,150421,A,4154.51607N,45.78950E,0.050,103142,0.000,595.200,7,0)")); -- cgit v1.2.3 From ae4deabf310135c68e0eab0a47470cf2cdf616a3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 23 Aug 2022 16:36:35 -0700 Subject: Support PUBX NMEA messages --- .../org/traccar/protocol/T55ProtocolDecoder.java | 61 +++++++++++++++++++++- .../traccar/protocol/T55ProtocolDecoderTest.java | 3 ++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 409c7e768..1529aae29 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -125,6 +125,30 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { .expression("([01])") // ignition .compile(); + private static final Pattern PATTERN_PUBX = new PatternBuilder() + .text("$PUBX,") + .number("(d+),") // index + .number("(dd)(dd)(dd).d+,") // time (hhmmss) + .number("(dd)(dd.d+),([NS]),") // latitude + .number("(ddd)(dd.d+),([EW]),") // longitude + .number("(-?d+.d+),") // altitude + .expression("(..),") // status + .number("(d+.d+),") // horizontal accuracy + .number("d+.d+,") // vertical accuracy + .number("(d+.d+),") // speed + .number("(d+.d+),") // course + .number("-?d+.d+,") // vertical velocity + .expression("[^,]*,") // corrections age + .number("(d+.d+),") // hdop + .number("(d+.d+),") // vdop + .number("d+.d+,") // tdop + .number("(d+),") // satellites + .number("(d+),") // device id + .number("d+") + .text("*") + .number("xx") // checksum + .compile(); + private Position position = null; private Position decodeGprmc( @@ -303,6 +327,39 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodePubx(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_PUBX, sentence); + if (!parser.matches()) { + return null; + } + + Position position = new Position(getProtocolName()); + + position.set(Position.KEY_INDEX, parser.nextInt()); + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS)); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setAltitude(parser.nextDouble()); + position.setValid(!parser.next().equals("NF")); + position.setAccuracy(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + + position.set(Position.KEY_HDOP, parser.nextDouble()); + position.set(Position.KEY_VDOP, parser.nextDouble()); + position.set(Position.KEY_SATELLITES, parser.nextInt()); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + return position; + } + + return null; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -357,6 +414,8 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { return decodeGpiop(deviceSession, sentence); } else if (sentence.startsWith("QZE")) { return decodeQze(channel, remoteAddress, sentence); + } else if (sentence.startsWith("$PUBX")) { + return decodePubx(channel, remoteAddress, sentence); } return null; diff --git a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java index 6ce47db94..1622f64f2 100644 --- a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class T55ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new T55ProtocolDecoder(null)); + verifyPosition(decoder, text( + "$PUBX,00,130209.00,3650.51159,N,01346.10602,E,785.947,D3,4.1,5.2,0.163,87.43,-0.054,7.0,0.88,1.21,0.88,24,01012,0*6D")); + verifyPosition(decoder, text( "QZE,868994033976700,35,28062020,113553,22.13673,114.57263,0,22,A,0")); -- cgit v1.2.3 From 5b174c67e5433a1ceceddc159ee6db6e229d5ba6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 Aug 2022 18:19:35 -0700 Subject: Geofences in events report (fix #4929) --- src/main/java/org/traccar/reports/common/ReportUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 253a6a2b6..7fff46f66 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -93,7 +93,7 @@ public class ReportUtils { public T getObject( long userId, Class clazz, long objectId) throws StorageException, SecurityException { return storage.getObject(clazz, new Request( - new Columns.Include("id"), + new Columns.All(), new Condition.And( new Condition.Equals("id", "id", objectId), new Condition.Permission(User.class, userId, clazz)))); -- cgit v1.2.3 From 4b2102596354446c291540a8c38e7cb4b0dd1086 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 29 Aug 2022 17:03:00 -0700 Subject: Allow saved commands (fix #4932) --- src/main/java/org/traccar/api/resource/CommandResource.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 60f1f8eb0..636b45023 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -97,7 +97,15 @@ public class CommandResource extends ExtendedObjectResource { @Path("send") public Response send(Command entity) throws Exception { permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); - permissionsService.checkRestriction(getUserId(), UserRestrictions::getLimitCommands); + if (entity.getId() > 0) { + permissionsService.checkPermission(Command.class, getUserId(), entity.getId()); + long deviceId = entity.getDeviceId(); + entity = storage.getObject(baseClass, new Request( + new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); + entity.setDeviceId(deviceId); + } else { + permissionsService.checkRestriction(getUserId(), UserRestrictions::getLimitCommands); + } permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); if (!commandsManager.sendCommand(entity)) { return Response.accepted(entity).build(); -- cgit v1.2.3 From d81296ccc31fd0528758a49d81432535141061bc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 30 Aug 2022 09:03:15 -0700 Subject: Reduce dependencies size --- build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1b1fbb738..5f7396dba 100644 --- a/build.gradle +++ b/build.gradle @@ -83,7 +83,9 @@ dependencies { implementation "com.sun.xml.bind:jaxb-impl:3.0.2" implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.141" - implementation "com.google.firebase:firebase-admin:9.0.0" + implementation ("com.google.firebase:firebase-admin:9.0.0") { + exclude group: 'com.google.cloud', module: 'google-cloud-firestore' + } testImplementation "junit:junit:4.13.2" testImplementation "org.mockito:mockito-core:3.+" } -- cgit v1.2.3 From fa78acf7876851e6e15e116ebe25f2f65a28fea0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 5 Sep 2022 10:25:34 -0700 Subject: Return default string value --- src/main/java/org/traccar/notification/PropertiesProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/notification/PropertiesProvider.java b/src/main/java/org/traccar/notification/PropertiesProvider.java index 4ffad432c..91887b5d4 100644 --- a/src/main/java/org/traccar/notification/PropertiesProvider.java +++ b/src/main/java/org/traccar/notification/PropertiesProvider.java @@ -37,7 +37,8 @@ public class PropertiesProvider { if (config != null) { return config.getString(key); } else { - return extendedModel.getString(key.getKey()); + String result = extendedModel.getString(key.getKey()); + return result != null ? result : key.getDefaultValue(); } } -- cgit v1.2.3 From 3ae99730940f0f108a0c655f0cb52c109ca57885 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 6 Sep 2022 19:00:45 -0700 Subject: Handle Firebase error responses --- src/main/java/org/traccar/notificators/NotificatorFirebase.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 6510963c7..3723a4226 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -84,7 +84,12 @@ public class NotificatorFirebase implements Notificator { .build(); try { - FirebaseMessaging.getInstance().sendMulticast(message); + var result = FirebaseMessaging.getInstance().sendMulticast(message); + for (var response : result.getResponses()) { + if (!response.isSuccessful()) { + throw new MessageException(response.getException()); + } + } } catch (FirebaseMessagingException e) { throw new MessageException(e); } -- cgit v1.2.3 From 210e2cd641bf89d9b86d247a237739d026208bcf Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 4 Sep 2022 14:21:12 +0100 Subject: Added files for G1rus protocol --- .../java/org/traccar/protocol/G1rusProtocol.java | 24 ++++++++++++++++++++++ .../org/traccar/protocol/G1rusProtocolDecoder.java | 18 ++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/G1rusProtocol.java create mode 100644 src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java diff --git a/src/main/java/org/traccar/protocol/G1rusProtocol.java b/src/main/java/org/traccar/protocol/G1rusProtocol.java new file mode 100644 index 000000000..0d77a8add --- /dev/null +++ b/src/main/java/org/traccar/protocol/G1rusProtocol.java @@ -0,0 +1,24 @@ +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; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class G1rusProtocol extends BaseProtocol { + + @Inject + public G1rusProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new G1rusProtocolDecoder(G1rusProtocol.this)); + } + }); + } +} diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java new file mode 100644 index 000000000..f6251d6c2 --- /dev/null +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Protocol; + +import java.net.SocketAddress; + +public class G1rusProtocolDecoder extends BaseProtocolDecoder { + public G1rusProtocolDecoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + } +} -- cgit v1.2.3 From 3899a7627ca99ce10f9f26a8f19477639510e298 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 10:35:17 +0100 Subject: Implemented basic REGULAR -> SYS -> GPS parsing --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 273 ++++++++++++++++++++- 1 file changed, 271 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index f6251d6c2..89303d1b1 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -1,18 +1,287 @@ package org.traccar.protocol; +import com.google.common.primitives.Doubles; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; +import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; +import org.traccar.model.Position; +import org.traccar.session.ConnectionManager; +import org.traccar.session.DeviceSession; import java.net.SocketAddress; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; public class G1rusProtocolDecoder extends BaseProtocolDecoder { public G1rusProtocolDecoder(Protocol protocol) { super(protocol); } + private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); + + /* Constants */ + private static final int G1RUS_HEAD_TAIL = 0xF8; + + private static final int G1RUS_TYPE_HEARTBEAT = 0; + + private static final int G1RUS_TYPE_BCD_MASK = 0b00111111; + private static final int G1RUS_TYPE_REGULAR = 1; + private static final int G1RUS_TYPE_SMS_FORWARD = 2; + private static final int G1RUS_TYPE_SERIAL_PASS_THROUGH = 3; + private static final int G1RUS_TYPE_MIXED = 4; + + private static final int G1RUS_TYPE_EVENT_MASK = 0b01000000; + private static final int G1RUS_TYPE_NON_EVENT = 0; + private static final int G1RUS_TYPE_EVENT = 1; + + private static final int G1RUS_TYPE_IMEI_MASK = 0b10000000; + private static final int G1RUS_TYPE_IMEI_LONG = 0; + private static final int G1RUS_TYPE_IMEI_SHORT = 1; + + private static final int G1RUS_DATA_SYS_MASK = 0b00000001; + private static final int G1RUS_DATA_GPS_MASK = 0b00000010; + private static final int G1RUS_DATA_GSM_MASK = 0b00000100; + private static final int G1RUS_DATA_COT_MASK = 0b00001000; + private static final int G1RUS_DATA_ADC_MASK = 0b00010000; + private static final int G1RUS_DATA_DTT_MASK = 0b00100000; + /* Reserved */ + private static final int G1RUS_DATA_ETD_MASK = 0b10000000; + + private static final int G1RUS_GPS_SIGN_MASK = 0b00000001; + private static final int G1RUS_GPS_POS_MASK = 0b00000010; + private static final int G1RUS_GPS_SPD_MASK = 0b00000100; + private static final int G1RUS_GPS_AZTH_MASK = 0b00001000; + private static final int G1RUS_GPS_ALT_MASK = 0b00010000; + private static final int G1RUS_GPS_HDOP_MASK = 0b00100000; + private static final int G1RUS_GPS_VDOP_MASK = 0b01000000; + private static final int G1RUS_GPS_STAT_MASK = 0b10000000; + + + private void decodeSYSSub(ByteBuf buf) { + LOGGER.info(""); + + buf.skipBytes(1); /* Total length */ + + /* NOTE: assuming order: + * Device name -> Firmware version -> Hardware version. + * TODO: actually check it. + */ + + /* Device name */ + byte devNameLen = (byte) buf.readUnsignedByte(); + byte[] devName = new byte[devNameLen & 0xF]; + buf.readBytes(devName); + String devNameString = new String(devName); + LOGGER.info("Device name: " + devNameString); + + /* Firmware version */ + byte firmwareLen = (byte) buf.readUnsignedByte(); + byte[] firmware = new byte[firmwareLen & 0xF]; + buf.readBytes(firmware); + String firmwareString = new String(firmware); + LOGGER.info("Firmware version: " + firmwareString); + + /* Hardware version */ + byte hardwareLen = (byte) buf.readUnsignedByte(); + byte[] hardware = new byte[hardwareLen & 0xF]; + buf.readBytes(hardware); + String hardwareString = new String(hardware); + LOGGER.info("Hardware version: " + hardwareString); + + LOGGER.info(""); + } + + + private void decodeGPSSub(ByteBuf buf, Position position) { + LOGGER.info(""); + + buf.skipBytes(1); /* Total length */ + + short subMask = (short) buf.readUnsignedShort(); + if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { + buf.skipBytes(1); + } + if ((subMask & G1RUS_GPS_POS_MASK) == G1RUS_GPS_POS_MASK) { + byte[] pos_buf = new byte[4]; + buf.readBytes(pos_buf); + position.setLatitude((float) Ints.fromByteArray(pos_buf) / 1000000); + LOGGER.info("Latitude: " + position.getLatitude()); + + buf.readBytes(pos_buf); + position.setLongitude((float) Ints.fromByteArray(pos_buf) / 1000000); + LOGGER.info("Longitude: " + position.getLongitude()); + } + if ((subMask & G1RUS_GPS_SPD_MASK) == G1RUS_GPS_SPD_MASK) { + position.setSpeed(buf.readUnsignedShort()); + LOGGER.info("Speed: " + position.getSpeed()); + } + if ((subMask & G1RUS_GPS_AZTH_MASK) == G1RUS_GPS_AZTH_MASK) { + position.setCourse(buf.readUnsignedShort()); + LOGGER.info("Course: " + position.getCourse()); + } + if ((subMask & G1RUS_GPS_ALT_MASK) == G1RUS_GPS_ALT_MASK) { + position.setAltitude(buf.readUnsignedShort()); + LOGGER.info("Altitude: " + position.getAltitude()); + } + if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { + buf.skipBytes(2); + } + if ((subMask & G1RUS_GPS_VDOP_MASK) == G1RUS_GPS_VDOP_MASK) { + buf.skipBytes(2); + } + + LOGGER.info(""); + } + + + private void decodeADCSub(ByteBuf buf, Position position) { + + } + + + private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, byte packetType) { + int timestamp_ = buf.readInt(); + long timestamp = (946684800 + timestamp_) * 1000L; /* Convert received time to proper UNIX timestamp */ + LOGGER.info("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); + + if ((packetType & G1RUS_TYPE_EVENT_MASK) != G1RUS_TYPE_NON_EVENT) { + buf.skipBytes(1); /* Event ID */ + } + + DeviceSession deviceSession = null; + Position position = null; + + short dataUploadingMask = (short) buf.readUnsignedShort(); + if ((dataUploadingMask & G1RUS_DATA_SYS_MASK) == G1RUS_DATA_SYS_MASK) { + decodeSYSSub(buf); + } + if ((dataUploadingMask & G1RUS_DATA_GPS_MASK) == G1RUS_DATA_GPS_MASK) { + deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(imei)); + if (deviceSession == null) { + return null; + } + position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.setTime(new Date(timestamp)); + + decodeGPSSub(buf, position); + } + if ((dataUploadingMask & G1RUS_DATA_GSM_MASK) == G1RUS_DATA_GSM_MASK) { + buf.skipBytes(buf.readUnsignedByte()); + } + if ((dataUploadingMask & G1RUS_DATA_COT_MASK) == G1RUS_DATA_COT_MASK) { + buf.skipBytes(buf.readUnsignedByte()); + } + if ((dataUploadingMask & G1RUS_DATA_ADC_MASK) == G1RUS_DATA_ADC_MASK) { + /*if (deviceSession == null) { + return null; + }*/ + + buf.skipBytes(buf.readUnsignedByte()); + // decodeADCSub(buf, position); + } + if ((dataUploadingMask & G1RUS_DATA_DTT_MASK) == G1RUS_DATA_DTT_MASK) { + buf.skipBytes(buf.readUnsignedByte()); + } + if ((dataUploadingMask & G1RUS_DATA_ETD_MASK) == G1RUS_DATA_ETD_MASK) { + buf.skipBytes(buf.readUnsignedByte()); + } + + return position; + } + + + private Object decodeSMSForward(ByteBuf buf) { + return null; + } + + + private Object decodeSerialPassThrough(ByteBuf buf) { + return null; + } + + + private void printPacketType(byte packetType) { + LOGGER.info("Packet type: " + (packetType == G1RUS_TYPE_HEARTBEAT ? "HEARTBEAT" : + "[" + ((packetType & G1RUS_TYPE_IMEI_MASK) == G1RUS_TYPE_IMEI_LONG ? "IMEI_LONG" : "IMEI_SHORT") + "]" + + "[" + ((packetType & G1RUS_TYPE_EVENT_MASK) == G1RUS_TYPE_NON_EVENT ? "NON-EVENT" : "EVENT") + "]" + + "[" + ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR ? "REGULAR" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD ? "SMS FORWARD" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH ? "PASS THROUGH" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED ? "MIXED PACKED" : "RESERVED/INVALID") + "]")); + } + + @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + ByteBuf buf = (ByteBuf) msg; + + buf.skipBytes(1); /* Head */ + + LOGGER.info("Protocol version: " + buf.readUnsignedByte()); + + byte packetType = (byte) buf.readUnsignedByte(); + printPacketType(packetType); + + byte[] imei = new byte[8]; + buf.readBytes(imei, 0, 7); + long imei_long = Longs.fromByteArray(imei); + LOGGER.info("IMEI: " + imei_long); + + List positions = null; + + if (packetType == G1RUS_TYPE_HEARTBEAT) { + return null; + } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { + positions = new LinkedList<>(); + Position position = decodeRegular(channel, remoteAddress, buf, imei_long, packetType); + if (position != null) { + positions.add(position); + } + } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { + return decodeSMSForward(buf); + } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH) { + return decodeSerialPassThrough(buf); + } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED) { + positions = new LinkedList<>(); + + while (buf.readableBytes() > 3) { + short subPacketLength = (short) buf.readUnsignedShort(); + byte subPacketType = (byte) buf.readUnsignedByte(); + printPacketType(subPacketType); + + if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { + Position position = decodeRegular(channel, remoteAddress, buf, imei_long, packetType); + if (position != null) { + positions.add(position); + } + } else { + try { + buf.skipBytes(subPacketLength - 1); + } catch (Exception e) { + return positions; + } + } + /* else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { + buf.skipBytes(subPacketLength - 1); + *//*decodeSMSForward(buf);*//* + } else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH) { + buf.skipBytes(subPacketLength - 1); + *//*decodeSerialPassThrough(buf);*//* + }*/ + } + } else { + LOGGER.error("Unknown packet type!"); + } + + buf.skipBytes(2); /* CRC */ /* TODO: actually check it */ + // buf.skipBytes(1); /* Tail */ + byte tail = (byte) buf.readUnsignedByte(); + + return positions; } } -- cgit v1.2.3 From 546f565023575c0975b7cc8fa3b9dea2f420918b Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 11:21:45 +0100 Subject: Added support for escaping byte sequences --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 107 +++++++++++++++------ 1 file changed, 75 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index 89303d1b1..d962e601e 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -3,6 +3,7 @@ package org.traccar.protocol; import com.google.common.primitives.Doubles; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; +import com.google.common.primitives.Shorts; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.slf4j.Logger; @@ -63,6 +64,50 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private static final int G1RUS_GPS_VDOP_MASK = 0b01000000; private static final int G1RUS_GPS_STAT_MASK = 0b10000000; + private static final int G1RUS_ESCAPE_CHAR = 0x1B; + + + private byte readUnsignedByteUnescaped(ByteBuf buf) { + byte first = (byte) buf.readUnsignedByte(); + if (first != G1RUS_ESCAPE_CHAR) { + return first; + } else { /* first == 0x1B */ + byte second = (byte) buf.readUnsignedByte(); + if (second == 0x00) { + return first; + } else { /* second == 0xE3 */ + return (byte) 0xF8; + } + } + } + + + private void readBytesUnescaped(ByteBuf buf, byte[] to) { + for (int i = 0; i < to.length; ++i) { + to[i] = readUnsignedByteUnescaped(buf); + } + } + + private void readBytesUnescaped(ByteBuf buf, byte[] to, int dstIndex, int length) { + for (int i = dstIndex; i < length; ++i) { + to[i] = readUnsignedByteUnescaped(buf); + } + } + + + private short readUnsignedShortUnescaped(ByteBuf buf) { + byte[] shortBuf = new byte[2]; + readBytesUnescaped(buf, shortBuf); + return Shorts.fromByteArray(shortBuf); + } + + + private int readIntUnescaped(ByteBuf buf) { + byte[] intBuf = new byte[4]; + readBytesUnescaped(buf, intBuf); + return Ints.fromByteArray(intBuf); + } + private void decodeSYSSub(ByteBuf buf) { LOGGER.info(""); @@ -75,23 +120,23 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { */ /* Device name */ - byte devNameLen = (byte) buf.readUnsignedByte(); + byte devNameLen = readUnsignedByteUnescaped(buf); byte[] devName = new byte[devNameLen & 0xF]; - buf.readBytes(devName); + readBytesUnescaped(buf, devName); String devNameString = new String(devName); LOGGER.info("Device name: " + devNameString); /* Firmware version */ - byte firmwareLen = (byte) buf.readUnsignedByte(); + byte firmwareLen = readUnsignedByteUnescaped(buf); byte[] firmware = new byte[firmwareLen & 0xF]; - buf.readBytes(firmware); + readBytesUnescaped(buf, firmware); String firmwareString = new String(firmware); LOGGER.info("Firmware version: " + firmwareString); /* Hardware version */ - byte hardwareLen = (byte) buf.readUnsignedByte(); + byte hardwareLen = readUnsignedByteUnescaped(buf); byte[] hardware = new byte[hardwareLen & 0xF]; - buf.readBytes(hardware); + readBytesUnescaped(buf, hardware); String hardwareString = new String(hardware); LOGGER.info("Hardware version: " + hardwareString); @@ -104,30 +149,30 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(1); /* Total length */ - short subMask = (short) buf.readUnsignedShort(); + short subMask = readUnsignedShortUnescaped(buf); if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { buf.skipBytes(1); } if ((subMask & G1RUS_GPS_POS_MASK) == G1RUS_GPS_POS_MASK) { byte[] pos_buf = new byte[4]; - buf.readBytes(pos_buf); + readBytesUnescaped(buf, pos_buf); position.setLatitude((float) Ints.fromByteArray(pos_buf) / 1000000); LOGGER.info("Latitude: " + position.getLatitude()); - buf.readBytes(pos_buf); + readBytesUnescaped(buf, pos_buf); position.setLongitude((float) Ints.fromByteArray(pos_buf) / 1000000); LOGGER.info("Longitude: " + position.getLongitude()); } if ((subMask & G1RUS_GPS_SPD_MASK) == G1RUS_GPS_SPD_MASK) { - position.setSpeed(buf.readUnsignedShort()); + position.setSpeed(readUnsignedShortUnescaped(buf)); LOGGER.info("Speed: " + position.getSpeed()); } if ((subMask & G1RUS_GPS_AZTH_MASK) == G1RUS_GPS_AZTH_MASK) { - position.setCourse(buf.readUnsignedShort()); + position.setCourse(readUnsignedShortUnescaped(buf)); LOGGER.info("Course: " + position.getCourse()); } if ((subMask & G1RUS_GPS_ALT_MASK) == G1RUS_GPS_ALT_MASK) { - position.setAltitude(buf.readUnsignedShort()); + position.setAltitude(readUnsignedShortUnescaped(buf)); LOGGER.info("Altitude: " + position.getAltitude()); } if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { @@ -147,7 +192,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, byte packetType) { - int timestamp_ = buf.readInt(); + int timestamp_ = readIntUnescaped(buf); long timestamp = (946684800 + timestamp_) * 1000L; /* Convert received time to proper UNIX timestamp */ LOGGER.info("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); @@ -158,7 +203,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = null; Position position = null; - short dataUploadingMask = (short) buf.readUnsignedShort(); + short dataUploadingMask = readUnsignedShortUnescaped(buf); if ((dataUploadingMask & G1RUS_DATA_SYS_MASK) == G1RUS_DATA_SYS_MASK) { decodeSYSSub(buf); } @@ -174,24 +219,24 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { decodeGPSSub(buf, position); } if ((dataUploadingMask & G1RUS_DATA_GSM_MASK) == G1RUS_DATA_GSM_MASK) { - buf.skipBytes(buf.readUnsignedByte()); + buf.skipBytes(readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_COT_MASK) == G1RUS_DATA_COT_MASK) { - buf.skipBytes(buf.readUnsignedByte()); + buf.skipBytes(readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_ADC_MASK) == G1RUS_DATA_ADC_MASK) { /*if (deviceSession == null) { return null; }*/ - buf.skipBytes(buf.readUnsignedByte()); + buf.skipBytes(readUnsignedByteUnescaped(buf)); // decodeADCSub(buf, position); } if ((dataUploadingMask & G1RUS_DATA_DTT_MASK) == G1RUS_DATA_DTT_MASK) { - buf.skipBytes(buf.readUnsignedByte()); + buf.skipBytes(readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_ETD_MASK) == G1RUS_DATA_ETD_MASK) { - buf.skipBytes(buf.readUnsignedByte()); + buf.skipBytes(readUnsignedByteUnescaped(buf)); } return position; @@ -220,15 +265,17 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; - buf.skipBytes(1); /* Head */ + if (buf.readUnsignedByte() != G1RUS_HEAD_TAIL) { + return null; + } - LOGGER.info("Protocol version: " + buf.readUnsignedByte()); + LOGGER.info("Protocol version: " + readUnsignedByteUnescaped(buf)); - byte packetType = (byte) buf.readUnsignedByte(); + byte packetType = readUnsignedByteUnescaped(buf); printPacketType(packetType); byte[] imei = new byte[8]; - buf.readBytes(imei, 0, 7); + readBytesUnescaped(buf, imei, 0, 7); long imei_long = Longs.fromByteArray(imei); LOGGER.info("IMEI: " + imei_long); @@ -249,22 +296,18 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED) { positions = new LinkedList<>(); - while (buf.readableBytes() > 3) { - short subPacketLength = (short) buf.readUnsignedShort(); - byte subPacketType = (byte) buf.readUnsignedByte(); + while (buf.readableBytes() > 5) { + short subPacketLength = readUnsignedShortUnescaped(buf); + byte subPacketType = readUnsignedByteUnescaped(buf); printPacketType(subPacketType); if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { - Position position = decodeRegular(channel, remoteAddress, buf, imei_long, packetType); + Position position = decodeRegular(channel, remoteAddress, buf, imei_long, subPacketType); if (position != null) { positions.add(position); } } else { - try { - buf.skipBytes(subPacketLength - 1); - } catch (Exception e) { - return positions; - } + buf.skipBytes(subPacketLength - 1); } /* else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { buf.skipBytes(subPacketLength - 1); -- cgit v1.2.3 From 37976d783941a0ccf3a5a6bf9a24316515217629 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 11:50:52 +0100 Subject: Fixed skipping escaped bytes --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 70 +++++++++++++--------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index d962e601e..6d4ae9d1f 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -67,8 +67,8 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private static final int G1RUS_ESCAPE_CHAR = 0x1B; - private byte readUnsignedByteUnescaped(ByteBuf buf) { - byte first = (byte) buf.readUnsignedByte(); + private short readUnsignedByteUnescaped(ByteBuf buf) { + short first = buf.readUnsignedByte(); if (first != G1RUS_ESCAPE_CHAR) { return first; } else { /* first == 0x1B */ @@ -76,21 +76,28 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { if (second == 0x00) { return first; } else { /* second == 0xE3 */ - return (byte) 0xF8; + return (short) 0xF8; } } } + private void skipBytesUnescaped(ByteBuf buf, int howMany) { + for (int i = 0; i < howMany; ++i) { + readUnsignedByteUnescaped(buf); + } + } + + private void readBytesUnescaped(ByteBuf buf, byte[] to) { for (int i = 0; i < to.length; ++i) { - to[i] = readUnsignedByteUnescaped(buf); + to[i] = (byte) readUnsignedByteUnescaped(buf); } } private void readBytesUnescaped(ByteBuf buf, byte[] to, int dstIndex, int length) { for (int i = dstIndex; i < length; ++i) { - to[i] = readUnsignedByteUnescaped(buf); + to[i] = (byte) readUnsignedByteUnescaped(buf); } } @@ -112,7 +119,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private void decodeSYSSub(ByteBuf buf) { LOGGER.info(""); - buf.skipBytes(1); /* Total length */ + skipBytesUnescaped(buf, 1); /* Total length */ /* NOTE: assuming order: * Device name -> Firmware version -> Hardware version. @@ -120,21 +127,21 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { */ /* Device name */ - byte devNameLen = readUnsignedByteUnescaped(buf); + short devNameLen = readUnsignedByteUnescaped(buf); byte[] devName = new byte[devNameLen & 0xF]; readBytesUnescaped(buf, devName); String devNameString = new String(devName); LOGGER.info("Device name: " + devNameString); /* Firmware version */ - byte firmwareLen = readUnsignedByteUnescaped(buf); + short firmwareLen = readUnsignedByteUnescaped(buf); byte[] firmware = new byte[firmwareLen & 0xF]; readBytesUnescaped(buf, firmware); String firmwareString = new String(firmware); LOGGER.info("Firmware version: " + firmwareString); /* Hardware version */ - byte hardwareLen = readUnsignedByteUnescaped(buf); + short hardwareLen = readUnsignedByteUnescaped(buf); byte[] hardware = new byte[hardwareLen & 0xF]; readBytesUnescaped(buf, hardware); String hardwareString = new String(hardware); @@ -147,11 +154,11 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private void decodeGPSSub(ByteBuf buf, Position position) { LOGGER.info(""); - buf.skipBytes(1); /* Total length */ + skipBytesUnescaped(buf, 1); /* Total length */ short subMask = readUnsignedShortUnescaped(buf); if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { - buf.skipBytes(1); + skipBytesUnescaped(buf, 1); } if ((subMask & G1RUS_GPS_POS_MASK) == G1RUS_GPS_POS_MASK) { byte[] pos_buf = new byte[4]; @@ -176,10 +183,10 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { LOGGER.info("Altitude: " + position.getAltitude()); } if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { - buf.skipBytes(2); + skipBytesUnescaped(buf, 2); } if ((subMask & G1RUS_GPS_VDOP_MASK) == G1RUS_GPS_VDOP_MASK) { - buf.skipBytes(2); + skipBytesUnescaped(buf, 2); } LOGGER.info(""); @@ -191,13 +198,13 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } - private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, byte packetType) { + private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, short packetType) { int timestamp_ = readIntUnescaped(buf); long timestamp = (946684800 + timestamp_) * 1000L; /* Convert received time to proper UNIX timestamp */ LOGGER.info("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); if ((packetType & G1RUS_TYPE_EVENT_MASK) != G1RUS_TYPE_NON_EVENT) { - buf.skipBytes(1); /* Event ID */ + skipBytesUnescaped(buf, 1); /* Event ID */ } DeviceSession deviceSession = null; @@ -219,24 +226,24 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { decodeGPSSub(buf, position); } if ((dataUploadingMask & G1RUS_DATA_GSM_MASK) == G1RUS_DATA_GSM_MASK) { - buf.skipBytes(readUnsignedByteUnescaped(buf)); + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_COT_MASK) == G1RUS_DATA_COT_MASK) { - buf.skipBytes(readUnsignedByteUnescaped(buf)); + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_ADC_MASK) == G1RUS_DATA_ADC_MASK) { /*if (deviceSession == null) { return null; }*/ - buf.skipBytes(readUnsignedByteUnescaped(buf)); + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); // decodeADCSub(buf, position); } if ((dataUploadingMask & G1RUS_DATA_DTT_MASK) == G1RUS_DATA_DTT_MASK) { - buf.skipBytes(readUnsignedByteUnescaped(buf)); + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_ETD_MASK) == G1RUS_DATA_ETD_MASK) { - buf.skipBytes(readUnsignedByteUnescaped(buf)); + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); } return position; @@ -253,7 +260,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } - private void printPacketType(byte packetType) { + private void printPacketType(short packetType) { LOGGER.info("Packet type: " + (packetType == G1RUS_TYPE_HEARTBEAT ? "HEARTBEAT" : "[" + ((packetType & G1RUS_TYPE_IMEI_MASK) == G1RUS_TYPE_IMEI_LONG ? "IMEI_LONG" : "IMEI_SHORT") + "]" + "[" + ((packetType & G1RUS_TYPE_EVENT_MASK) == G1RUS_TYPE_NON_EVENT ? "NON-EVENT" : "EVENT") + "]" + @@ -271,7 +278,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { LOGGER.info("Protocol version: " + readUnsignedByteUnescaped(buf)); - byte packetType = readUnsignedByteUnescaped(buf); + short packetType = readUnsignedByteUnescaped(buf); printPacketType(packetType); byte[] imei = new byte[8]; @@ -298,7 +305,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { while (buf.readableBytes() > 5) { short subPacketLength = readUnsignedShortUnescaped(buf); - byte subPacketType = readUnsignedByteUnescaped(buf); + short subPacketType = readUnsignedByteUnescaped(buf); printPacketType(subPacketType); if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { @@ -307,13 +314,13 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { positions.add(position); } } else { - buf.skipBytes(subPacketLength - 1); + skipBytesUnescaped(buf, subPacketLength - 1); } /* else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { - buf.skipBytes(subPacketLength - 1); + skipBytesUnescaped(buf, subPacketLength - 1); *//*decodeSMSForward(buf);*//* } else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH) { - buf.skipBytes(subPacketLength - 1); + skipBytesUnescaped(buf, subPacketLength - 1); *//*decodeSerialPassThrough(buf);*//* }*/ } @@ -321,9 +328,14 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { LOGGER.error("Unknown packet type!"); } - buf.skipBytes(2); /* CRC */ /* TODO: actually check it */ - // buf.skipBytes(1); /* Tail */ - byte tail = (byte) buf.readUnsignedByte(); + skipBytesUnescaped(buf, 2); /* CRC */ /* TODO: actually check it */ + // skipBytesUnescaped(buf, 1); /* Tail */ + short tail = buf.readUnsignedByte(); + if (tail == G1RUS_HEAD_TAIL) { + LOGGER.info("Tail: OK"); + } else { + LOGGER.error("Tail: FAIL!"); + } return positions; } -- cgit v1.2.3 From 24cb3a2faaa1fba33983e4e942af8d0c35df5802 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 12:19:23 +0100 Subject: Removed extra lines --- src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index 6d4ae9d1f..056fc2d4d 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -1,6 +1,5 @@ package org.traccar.protocol; -import com.google.common.primitives.Doubles; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.google.common.primitives.Shorts; @@ -329,7 +328,6 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } skipBytesUnescaped(buf, 2); /* CRC */ /* TODO: actually check it */ - // skipBytesUnescaped(buf, 1); /* Tail */ short tail = buf.readUnsignedByte(); if (tail == G1RUS_HEAD_TAIL) { LOGGER.info("Tail: OK"); -- cgit v1.2.3 From 6196ea366cfc5c668ef35940bcac50672badd82d Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 12:56:16 +0100 Subject: Added decoding of ADC sub-packet --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 49 +++++++++++++++++----- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index 056fc2d4d..24bd69d45 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -63,6 +63,8 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private static final int G1RUS_GPS_VDOP_MASK = 0b01000000; private static final int G1RUS_GPS_STAT_MASK = 0b10000000; + private static final int G1RUS_ADC_DATA_MASK = 0b0000111111111111; + private static final int G1RUS_ESCAPE_CHAR = 0x1B; @@ -101,7 +103,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } - private short readUnsignedShortUnescaped(ByteBuf buf) { + private int readUnsignedShortUnescaped(ByteBuf buf) { byte[] shortBuf = new byte[2]; readBytesUnescaped(buf, shortBuf); return Shorts.fromByteArray(shortBuf); @@ -155,7 +157,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { skipBytesUnescaped(buf, 1); /* Total length */ - short subMask = readUnsignedShortUnescaped(buf); + int subMask = readUnsignedShortUnescaped(buf); if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { skipBytesUnescaped(buf, 1); } @@ -192,8 +194,36 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { } + private int getADValue(int rawValue) { + final int AD_MIN = -10; + final int AD_MAX = 100; + + return rawValue * (AD_MAX - AD_MIN) / 4096 + AD_MIN; + } + + private void decodeADCSub(ByteBuf buf, Position position) { + LOGGER.info(""); + + skipBytesUnescaped(buf, 1); + + /* NOTE: assuming order: + * External battery voltage -> Backup battery voltage -> Device temperature voltage. + * TODO: actually check this. + */ + int externalVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; + LOGGER.info("External voltage: " + getADValue(externalVoltage) + "V [" + externalVoltage + "]"); + + int backupVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; + LOGGER.info("Backup voltage: " + getADValue(backupVoltage) + "V [" + backupVoltage + "]"); + position.set(Position.KEY_BATTERY, getADValue(backupVoltage)); + + int temperature = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; + LOGGER.info("Device temperature: " + getADValue(temperature) + "°C [" + temperature + "]"); + position.set(Position.KEY_DEVICE_TEMP, getADValue(temperature)); + + LOGGER.info(""); } @@ -209,7 +239,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = null; Position position = null; - short dataUploadingMask = readUnsignedShortUnescaped(buf); + int dataUploadingMask = readUnsignedShortUnescaped(buf); if ((dataUploadingMask & G1RUS_DATA_SYS_MASK) == G1RUS_DATA_SYS_MASK) { decodeSYSSub(buf); } @@ -231,12 +261,11 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); } if ((dataUploadingMask & G1RUS_DATA_ADC_MASK) == G1RUS_DATA_ADC_MASK) { - /*if (deviceSession == null) { - return null; - }*/ - - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); - // decodeADCSub(buf, position); + if (deviceSession == null) { + skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); + } else { + decodeADCSub(buf, position); + } } if ((dataUploadingMask & G1RUS_DATA_DTT_MASK) == G1RUS_DATA_DTT_MASK) { skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); @@ -303,7 +332,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { positions = new LinkedList<>(); while (buf.readableBytes() > 5) { - short subPacketLength = readUnsignedShortUnescaped(buf); + int subPacketLength = readUnsignedShortUnescaped(buf); short subPacketType = readUnsignedByteUnescaped(buf); printPacketType(subPacketType); -- cgit v1.2.3 From 5dd61da7a9927bb28c880a5fe50997170aaf536c Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 13:06:49 +0100 Subject: Added support for decoding more data from GPS sub-packet --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index 24bd69d45..fd30b170e 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -159,16 +159,20 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { int subMask = readUnsignedShortUnescaped(buf); if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { - skipBytesUnescaped(buf, 1); + short signValid = readUnsignedByteUnescaped(buf); + LOGGER.info("Fix sign: " + ((signValid & 0b1100000) >> 5)); + LOGGER.info("Satellite number: " + (signValid & 0b0011111)); + position.setValid(((signValid & 0b1100000) >> 5) == 2); + position.set(Position.KEY_SATELLITES, signValid & 0b0011111); } if ((subMask & G1RUS_GPS_POS_MASK) == G1RUS_GPS_POS_MASK) { - byte[] pos_buf = new byte[4]; - readBytesUnescaped(buf, pos_buf); - position.setLatitude((float) Ints.fromByteArray(pos_buf) / 1000000); + byte[] posBuf = new byte[4]; + readBytesUnescaped(buf, posBuf); + position.setLatitude((float) Ints.fromByteArray(posBuf) / 1000000); LOGGER.info("Latitude: " + position.getLatitude()); - readBytesUnescaped(buf, pos_buf); - position.setLongitude((float) Ints.fromByteArray(pos_buf) / 1000000); + readBytesUnescaped(buf, posBuf); + position.setLongitude((float) Ints.fromByteArray(posBuf) / 1000000); LOGGER.info("Longitude: " + position.getLongitude()); } if ((subMask & G1RUS_GPS_SPD_MASK) == G1RUS_GPS_SPD_MASK) { @@ -184,10 +188,12 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { LOGGER.info("Altitude: " + position.getAltitude()); } if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { - skipBytesUnescaped(buf, 2); + position.set(Position.KEY_HDOP, readUnsignedShortUnescaped(buf)); + LOGGER.info("HDOP: " + position.getAttributes().get(Position.KEY_HDOP)); } if ((subMask & G1RUS_GPS_VDOP_MASK) == G1RUS_GPS_VDOP_MASK) { - skipBytesUnescaped(buf, 2); + position.set(Position.KEY_VDOP, readUnsignedShortUnescaped(buf)); + LOGGER.info("VDOP: " + position.getAttributes().get(Position.KEY_VDOP)); } LOGGER.info(""); @@ -311,8 +317,8 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { byte[] imei = new byte[8]; readBytesUnescaped(buf, imei, 0, 7); - long imei_long = Longs.fromByteArray(imei); - LOGGER.info("IMEI: " + imei_long); + long imeiLong = Longs.fromByteArray(imei); + LOGGER.info("IMEI: " + imeiLong); List positions = null; @@ -320,7 +326,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { return null; } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { positions = new LinkedList<>(); - Position position = decodeRegular(channel, remoteAddress, buf, imei_long, packetType); + Position position = decodeRegular(channel, remoteAddress, buf, imeiLong, packetType); if (position != null) { positions.add(position); } @@ -337,7 +343,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { printPacketType(subPacketType); if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { - Position position = decodeRegular(channel, remoteAddress, buf, imei_long, subPacketType); + Position position = decodeRegular(channel, remoteAddress, buf, imeiLong, subPacketType); if (position != null) { positions.add(position); } -- cgit v1.2.3 From 3574169d57b9619ec4dfb90694c9c9ae37c1896f Mon Sep 17 00:00:00 2001 From: anton2920 Date: Mon, 5 Sep 2022 13:10:22 +0100 Subject: Added G1RUS port to default.xml --- setup/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/default.xml b/setup/default.xml index 607efc35f..f5e28e18b 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -284,5 +284,5 @@ 5239 5240 5241 - + 5242 -- cgit v1.2.3 From d55ae464806430ee57bbd56737f024ead95748a2 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Wed, 7 Sep 2022 09:48:29 +0100 Subject: Moved logger messages to debug logs --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 52 +++++++++++----------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index fd30b170e..b1b7230e1 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -118,7 +118,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private void decodeSYSSub(ByteBuf buf) { - LOGGER.info(""); + LOGGER.debug(""); skipBytesUnescaped(buf, 1); /* Total length */ @@ -132,36 +132,36 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { byte[] devName = new byte[devNameLen & 0xF]; readBytesUnescaped(buf, devName); String devNameString = new String(devName); - LOGGER.info("Device name: " + devNameString); + LOGGER.debug("Device name: " + devNameString); /* Firmware version */ short firmwareLen = readUnsignedByteUnescaped(buf); byte[] firmware = new byte[firmwareLen & 0xF]; readBytesUnescaped(buf, firmware); String firmwareString = new String(firmware); - LOGGER.info("Firmware version: " + firmwareString); + LOGGER.debug("Firmware version: " + firmwareString); /* Hardware version */ short hardwareLen = readUnsignedByteUnescaped(buf); byte[] hardware = new byte[hardwareLen & 0xF]; readBytesUnescaped(buf, hardware); String hardwareString = new String(hardware); - LOGGER.info("Hardware version: " + hardwareString); + LOGGER.debug("Hardware version: " + hardwareString); - LOGGER.info(""); + LOGGER.debug(""); } private void decodeGPSSub(ByteBuf buf, Position position) { - LOGGER.info(""); + LOGGER.debug(""); skipBytesUnescaped(buf, 1); /* Total length */ int subMask = readUnsignedShortUnescaped(buf); if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { short signValid = readUnsignedByteUnescaped(buf); - LOGGER.info("Fix sign: " + ((signValid & 0b1100000) >> 5)); - LOGGER.info("Satellite number: " + (signValid & 0b0011111)); + LOGGER.debug("Fix sign: " + ((signValid & 0b1100000) >> 5)); + LOGGER.debug("Satellite number: " + (signValid & 0b0011111)); position.setValid(((signValid & 0b1100000) >> 5) == 2); position.set(Position.KEY_SATELLITES, signValid & 0b0011111); } @@ -169,34 +169,34 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { byte[] posBuf = new byte[4]; readBytesUnescaped(buf, posBuf); position.setLatitude((float) Ints.fromByteArray(posBuf) / 1000000); - LOGGER.info("Latitude: " + position.getLatitude()); + LOGGER.debug("Latitude: " + position.getLatitude()); readBytesUnescaped(buf, posBuf); position.setLongitude((float) Ints.fromByteArray(posBuf) / 1000000); - LOGGER.info("Longitude: " + position.getLongitude()); + LOGGER.debug("Longitude: " + position.getLongitude()); } if ((subMask & G1RUS_GPS_SPD_MASK) == G1RUS_GPS_SPD_MASK) { position.setSpeed(readUnsignedShortUnescaped(buf)); - LOGGER.info("Speed: " + position.getSpeed()); + LOGGER.debug("Speed: " + position.getSpeed()); } if ((subMask & G1RUS_GPS_AZTH_MASK) == G1RUS_GPS_AZTH_MASK) { position.setCourse(readUnsignedShortUnescaped(buf)); - LOGGER.info("Course: " + position.getCourse()); + LOGGER.debug("Course: " + position.getCourse()); } if ((subMask & G1RUS_GPS_ALT_MASK) == G1RUS_GPS_ALT_MASK) { position.setAltitude(readUnsignedShortUnescaped(buf)); - LOGGER.info("Altitude: " + position.getAltitude()); + LOGGER.debug("Altitude: " + position.getAltitude()); } if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { position.set(Position.KEY_HDOP, readUnsignedShortUnescaped(buf)); - LOGGER.info("HDOP: " + position.getAttributes().get(Position.KEY_HDOP)); + LOGGER.debug("HDOP: " + position.getAttributes().get(Position.KEY_HDOP)); } if ((subMask & G1RUS_GPS_VDOP_MASK) == G1RUS_GPS_VDOP_MASK) { position.set(Position.KEY_VDOP, readUnsignedShortUnescaped(buf)); - LOGGER.info("VDOP: " + position.getAttributes().get(Position.KEY_VDOP)); + LOGGER.debug("VDOP: " + position.getAttributes().get(Position.KEY_VDOP)); } - LOGGER.info(""); + LOGGER.debug(""); } @@ -209,7 +209,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private void decodeADCSub(ByteBuf buf, Position position) { - LOGGER.info(""); + LOGGER.debug(""); skipBytesUnescaped(buf, 1); @@ -219,24 +219,24 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { */ int externalVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.info("External voltage: " + getADValue(externalVoltage) + "V [" + externalVoltage + "]"); + LOGGER.debug("External voltage: " + getADValue(externalVoltage) + "V [" + externalVoltage + "]"); int backupVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.info("Backup voltage: " + getADValue(backupVoltage) + "V [" + backupVoltage + "]"); + LOGGER.debug("Backup voltage: " + getADValue(backupVoltage) + "V [" + backupVoltage + "]"); position.set(Position.KEY_BATTERY, getADValue(backupVoltage)); int temperature = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.info("Device temperature: " + getADValue(temperature) + "°C [" + temperature + "]"); + LOGGER.debug("Device temperature: " + getADValue(temperature) + "°C [" + temperature + "]"); position.set(Position.KEY_DEVICE_TEMP, getADValue(temperature)); - LOGGER.info(""); + LOGGER.debug(""); } private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, short packetType) { int timestamp_ = readIntUnescaped(buf); long timestamp = (946684800 + timestamp_) * 1000L; /* Convert received time to proper UNIX timestamp */ - LOGGER.info("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); + LOGGER.debug("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); if ((packetType & G1RUS_TYPE_EVENT_MASK) != G1RUS_TYPE_NON_EVENT) { skipBytesUnescaped(buf, 1); /* Event ID */ @@ -295,7 +295,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { private void printPacketType(short packetType) { - LOGGER.info("Packet type: " + (packetType == G1RUS_TYPE_HEARTBEAT ? "HEARTBEAT" : + LOGGER.debug("Packet type: " + (packetType == G1RUS_TYPE_HEARTBEAT ? "HEARTBEAT" : "[" + ((packetType & G1RUS_TYPE_IMEI_MASK) == G1RUS_TYPE_IMEI_LONG ? "IMEI_LONG" : "IMEI_SHORT") + "]" + "[" + ((packetType & G1RUS_TYPE_EVENT_MASK) == G1RUS_TYPE_NON_EVENT ? "NON-EVENT" : "EVENT") + "]" + "[" + ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR ? "REGULAR" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD ? "SMS FORWARD" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH ? "PASS THROUGH" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED ? "MIXED PACKED" : "RESERVED/INVALID") + "]")); @@ -310,7 +310,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { return null; } - LOGGER.info("Protocol version: " + readUnsignedByteUnescaped(buf)); + LOGGER.debug("Protocol version: " + readUnsignedByteUnescaped(buf)); short packetType = readUnsignedByteUnescaped(buf); printPacketType(packetType); @@ -318,7 +318,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { byte[] imei = new byte[8]; readBytesUnescaped(buf, imei, 0, 7); long imeiLong = Longs.fromByteArray(imei); - LOGGER.info("IMEI: " + imeiLong); + LOGGER.debug("IMEI: " + imeiLong); List positions = null; @@ -365,7 +365,7 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { skipBytesUnescaped(buf, 2); /* CRC */ /* TODO: actually check it */ short tail = buf.readUnsignedByte(); if (tail == G1RUS_HEAD_TAIL) { - LOGGER.info("Tail: OK"); + LOGGER.debug("Tail: OK"); } else { LOGGER.error("Tail: FAIL!"); } -- cgit v1.2.3 From 1359371f83393e4a6a5dcbc0df03ab1b33bebde5 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 17:32:01 +0100 Subject: Added high-level payload parsing --- .../traccar/protocol/PiligrimProtocolDecoder.java | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 244df6806..dca8b1329 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -30,6 +30,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -150,6 +151,33 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { } return positions; + } else if (uri.startsWith("/push.do")) { + /* Getting payload */ + ByteBuf content_stream = request.content(); + byte[] payload_bytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; + content_stream.readBytes(payload_bytes); + String payload = new String(payload_bytes); + + /* Payload structure: + * &phone&message + */ + String[] payload_parts = payload.split("&"); + System.out.println("Payload parts: " + Arrays.toString(payload_parts)); + String phone_number = payload_parts[1].substring(12); + String message = payload_parts[2].substring(8); + System.out.println("Phone number: " + phone_number); + System.out.println("Message: " + message); + + /* Supported message structure: + * GPS NMEA Command; GSM info; Unknown; Battery voltage? + */ + if (message.startsWith("$GPRMC")) { + System.out.println("Supported message"); + } else { + System.out.println("Unsupported message"); + } + + System.out.println("Finish"); } return null; -- cgit v1.2.3 From 16197c4bec4da40372da7505c6b2093da6b743f5 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 17:47:13 +0100 Subject: Added high-level parsing of message field --- .../traccar/protocol/PiligrimProtocolDecoder.java | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index dca8b1329..29b6d9ef0 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -168,11 +168,28 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { System.out.println("Phone number: " + phone_number); System.out.println("Message: " + message); - /* Supported message structure: - * GPS NMEA Command; GSM info; Unknown; Battery voltage? - */ if (message.startsWith("$GPRMC")) { + /* Supported message structure: + * GPS NMEA Command; GSM info; Unknown; Battery voltage? + * Example: $GPRMC,180752.000,A,5314.0857,N,03421.8173,E,0.00,104.74,220722,,,A,V* 29,05; GSM: 250-01 0b54-0519,1c30,3e96,3ebe,412e 25; S; Batt: 405,M + */ System.out.println("Supported message"); + + String[] message_parts = message.split(";"); + System.out.println("Message parts: " + Arrays.toString(message_parts)); + + /* Parsing GPS */ + String unprocessed_gps_command = message_parts[0]; + + /* Getting rid of checksum */ + String gps_command = unprocessed_gps_command.replaceFirst("A,V[*].*", ""); + System.out.println("GPS command: " + gps_command); + + /* Parsing other fields */ + /* String gsm_info = message_parts[1]; */ + /* String unknown = message_parts[2]; */ + String battery_info = message_parts[3].substring(7).substring(0, 3); + System.out.println("Battery: " + battery_info); } else { System.out.println("Unsupported message"); } -- cgit v1.2.3 From 3ead0772172daeb3d6fedab5f04a32c33b9d5ebb Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 17:53:21 +0100 Subject: Added NMEA parser (that doesn't s**ck) --- src/main/java/org/traccar/helper/NMEA.java | 126 +++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/main/java/org/traccar/helper/NMEA.java diff --git a/src/main/java/org/traccar/helper/NMEA.java b/src/main/java/org/traccar/helper/NMEA.java new file mode 100644 index 000000000..cae47a8f6 --- /dev/null +++ b/src/main/java/org/traccar/helper/NMEA.java @@ -0,0 +1,126 @@ +package org.traccar.helper; + +import java.util.HashMap; +import java.util.Map; + + +public class NMEA { + + // fucking java interfaces + interface SentenceParser { + public boolean parse(String[] tokens, GPSPosition position); + } + + // utils + static float Latitude2Decimal(String lat, String NS) { + float med = Float.parseFloat(lat.substring(2)) / 60.0f; + med += Float.parseFloat(lat.substring(0, 2)); + if (NS.startsWith("S")) { + med = -med; + } + return med; + } + + static float Longitude2Decimal(String lon, String WE) { + float med = Float.parseFloat(lon.substring(3)) / 60.0f; + med += Float.parseFloat(lon.substring(0, 3)); + if (WE.startsWith("W")) { + med = -med; + } + return med; + } + + // parsers + class GPGGA implements SentenceParser { + public boolean parse(String[] tokens, GPSPosition position) { + position.time = Float.parseFloat(tokens[1]); + position.lat = Latitude2Decimal(tokens[2], tokens[3]); + position.lon = Longitude2Decimal(tokens[4], tokens[5]); + position.quality = Integer.parseInt(tokens[6]); + position.altitude = Float.parseFloat(tokens[9]); + return true; + } + } + + class GPGGL implements SentenceParser { + public boolean parse(String[] tokens, GPSPosition position) { + position.lat = Latitude2Decimal(tokens[1], tokens[2]); + position.lon = Longitude2Decimal(tokens[3], tokens[4]); + position.time = Float.parseFloat(tokens[5]); + return true; + } + } + + class GPRMC implements SentenceParser { + public boolean parse(String[] tokens, GPSPosition position) { + position.time = Float.parseFloat(tokens[1]); + position.lat = Latitude2Decimal(tokens[3], tokens[4]); + position.lon = Longitude2Decimal(tokens[5], tokens[6]); + position.velocity = Float.parseFloat(tokens[7]); + position.dir = Float.parseFloat(tokens[8]); + return true; + } + } + + class GPVTG implements SentenceParser { + public boolean parse(String[] tokens, GPSPosition position) { + position.dir = Float.parseFloat(tokens[3]); + return true; + } + } + + class GPRMZ implements SentenceParser { + public boolean parse(String[] tokens, GPSPosition position) { + position.altitude = Float.parseFloat(tokens[1]); + return true; + } + } + + public class GPSPosition { + public float time = 0.0f; + public float lat = 0.0f; + public float lon = 0.0f; + public boolean fixed = false; + public int quality = 0; + public float dir = 0.0f; + public float altitude = 0.0f; + public float velocity = 0.0f; + + public void updatefix() { + fixed = quality > 0; + } + + public String toString() { + return String.format("POSITION: lat: %f, lon: %f, time: %f, Q: %d, dir: %f, alt: %f, vel: %f", lat, lon, time, quality, dir, altitude, velocity); + } + } + + GPSPosition position = new GPSPosition(); + + private static final Map sentenceParsers = new HashMap(); + + public NMEA() { + sentenceParsers.put("GPGGA", new GPGGA()); + sentenceParsers.put("GPGGL", new GPGGL()); + sentenceParsers.put("GPRMC", new GPRMC()); + sentenceParsers.put("GPRMZ", new GPRMZ()); + //only really good GPS devices have this sentence but ... + sentenceParsers.put("GPVTG", new GPVTG()); + } + + public GPSPosition parse(String line) { + + if (line.startsWith("$")) { + String nmea = line.substring(1); + String[] tokens = nmea.split(","); + String type = tokens[0]; + //TODO check crc + if (sentenceParsers.containsKey(type)) { + sentenceParsers.get(type).parse(tokens, position); + } + position.updatefix(); + } + + return position; + } +} -- cgit v1.2.3 From 2274b42c6b1c7b1ef90e3ec4e5e956afe66eaa6d Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 18:01:41 +0100 Subject: Added parsing of GPS NMEA message --- .../java/org/traccar/protocol/PiligrimProtocolDecoder.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 29b6d9ef0..7f9d20822 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -26,6 +26,7 @@ import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; +import org.traccar.helper.NMEA; import org.traccar.model.Position; import java.net.SocketAddress; @@ -163,7 +164,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { */ String[] payload_parts = payload.split("&"); System.out.println("Payload parts: " + Arrays.toString(payload_parts)); - String phone_number = payload_parts[1].substring(12); + String phone_number = payload_parts[1].substring(15); String message = payload_parts[2].substring(8); System.out.println("Phone number: " + phone_number); System.out.println("Message: " + message); @@ -185,6 +186,14 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { String gps_command = unprocessed_gps_command.replaceFirst("A,V[*].*", ""); System.out.println("GPS command: " + gps_command); + NMEA gps_parser = new NMEA(); + + NMEA.GPSPosition gps_position = gps_parser.parse(gps_command); + + System.out.println("Time: " + gps_position.time); + System.out.println("Coordinates: " + gps_position.lat + " " + gps_position.lon); + System.out.println("Speed over ground: " + gps_position.velocity + " knots"); + /* Parsing other fields */ /* String gsm_info = message_parts[1]; */ /* String unknown = message_parts[2]; */ -- cgit v1.2.3 From 62b38f2ccf0db60e7e953485898a1d3bf5c452e0 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 18:36:33 +0100 Subject: WIP: Added position return --- .../traccar/protocol/PiligrimProtocolDecoder.java | 28 ++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 7f9d20822..967adb82b 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -21,6 +21,7 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; +import net.fortuna.ical4j.model.DateTime; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.session.DeviceSession; import org.traccar.Protocol; @@ -32,6 +33,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -153,6 +155,13 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { return positions; } else if (uri.startsWith("/push.do")) { + sendResponse(channel, "PUSH.DO: OK"); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, "123456"); + if (deviceSession == null) { + return null; + } + /* Getting payload */ ByteBuf content_stream = request.content(); byte[] payload_bytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; @@ -199,11 +208,26 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { /* String unknown = message_parts[2]; */ String battery_info = message_parts[3].substring(7).substring(0, 3); System.out.println("Battery: " + battery_info); + + /* Constructing response */ + Position position = new Position(getProtocolName()); + + position.setDeviceId(deviceSession.getDeviceId()); + position.setValid(true); + position.setLatitude(gps_position.lat); + position.setLongitude(gps_position.lon); + position.setTime(new Date(System.currentTimeMillis())); + position.setSpeed(gps_position.velocity); + position.setCourse(gps_position.dir); + position.setAccuracy(gps_position.quality); + position.set(Position.KEY_BATTERY, Integer.parseInt(battery_info) / 100); + + System.out.println("Supported message finish"); + + return position; } else { System.out.println("Unsupported message"); } - - System.out.println("Finish"); } return null; -- cgit v1.2.3 From b66d4c3b3250edac4762176277f4f07bc2e74d8e Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 18:43:30 +0100 Subject: Commented out 'System.out.println()'s --- .../org/traccar/protocol/PiligrimProtocolDecoder.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 967adb82b..775032b64 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -172,11 +172,11 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { * &phone&message */ String[] payload_parts = payload.split("&"); - System.out.println("Payload parts: " + Arrays.toString(payload_parts)); + /* System.out.println("Payload parts: " + Arrays.toString(payload_parts)); */ String phone_number = payload_parts[1].substring(15); String message = payload_parts[2].substring(8); - System.out.println("Phone number: " + phone_number); - System.out.println("Message: " + message); + /* System.out.println("Phone number: " + phone_number); */ + /* System.out.println("Message: " + message); */ if (message.startsWith("$GPRMC")) { /* Supported message structure: @@ -186,28 +186,28 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { System.out.println("Supported message"); String[] message_parts = message.split(";"); - System.out.println("Message parts: " + Arrays.toString(message_parts)); + /* System.out.println("Message parts: " + Arrays.toString(message_parts)); */ /* Parsing GPS */ String unprocessed_gps_command = message_parts[0]; /* Getting rid of checksum */ String gps_command = unprocessed_gps_command.replaceFirst("A,V[*].*", ""); - System.out.println("GPS command: " + gps_command); + /* System.out.println("GPS command: " + gps_command); */ NMEA gps_parser = new NMEA(); NMEA.GPSPosition gps_position = gps_parser.parse(gps_command); - System.out.println("Time: " + gps_position.time); - System.out.println("Coordinates: " + gps_position.lat + " " + gps_position.lon); - System.out.println("Speed over ground: " + gps_position.velocity + " knots"); + /* System.out.println("Time: " + gps_position.time); */ + /* System.out.println("Coordinates: " + gps_position.lat + " " + gps_position.lon); */ + /* System.out.println("Speed over ground: " + gps_position.velocity + " knots"); */ /* Parsing other fields */ /* String gsm_info = message_parts[1]; */ /* String unknown = message_parts[2]; */ String battery_info = message_parts[3].substring(7).substring(0, 3); - System.out.println("Battery: " + battery_info); + /* System.out.println("Battery: " + battery_info); */ /* Constructing response */ Position position = new Position(getProtocolName()); -- cgit v1.2.3 From 26e3d616ef17db2c30da0e9c8c0a7a1e9182cc6c Mon Sep 17 00:00:00 2001 From: anton2920 Date: Sun, 24 Jul 2022 19:18:49 +0100 Subject: Added workaround for 'ALARM KEY;' --- src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 775032b64..d1f667f6f 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -173,8 +173,8 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { */ String[] payload_parts = payload.split("&"); /* System.out.println("Payload parts: " + Arrays.toString(payload_parts)); */ - String phone_number = payload_parts[1].substring(15); - String message = payload_parts[2].substring(8); + /* String phone_number = payload_parts[1].substring(15); */ + String message = payload_parts[2].substring(8).replaceFirst("ALARM KEY; ", ""); /* System.out.println("Phone number: " + phone_number); */ /* System.out.println("Message: " + message); */ @@ -220,6 +220,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { position.setSpeed(gps_position.velocity); position.setCourse(gps_position.dir); position.setAccuracy(gps_position.quality); + position.setAltitude(gps_position.altitude); position.set(Position.KEY_BATTERY, Integer.parseInt(battery_info) / 100); System.out.println("Supported message finish"); -- cgit v1.2.3 From b3caf3c1cee6cb665e8ac05be35d9258c353771e Mon Sep 17 00:00:00 2001 From: anton2920 Date: Tue, 6 Sep 2022 10:53:38 +0100 Subject: Replaced hard-coded ID with phone number --- .../org/traccar/protocol/PiligrimProtocolDecoder.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index d1f667f6f..da8991bd3 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -157,11 +157,6 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { } else if (uri.startsWith("/push.do")) { sendResponse(channel, "PUSH.DO: OK"); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, "123456"); - if (deviceSession == null) { - return null; - } - /* Getting payload */ ByteBuf content_stream = request.content(); byte[] payload_bytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; @@ -173,7 +168,15 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { */ String[] payload_parts = payload.split("&"); /* System.out.println("Payload parts: " + Arrays.toString(payload_parts)); */ - /* String phone_number = payload_parts[1].substring(15); */ + String phone_number = payload_parts[1].substring(15); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phone_number); + if (deviceSession == null) { + return null; + } + + /* TODO: generalize this process; + * TODO: use keys for flags in 'positions'. + */ String message = payload_parts[2].substring(8).replaceFirst("ALARM KEY; ", ""); /* System.out.println("Phone number: " + phone_number); */ /* System.out.println("Message: " + message); */ -- cgit v1.2.3 From bd49d52fc47dcb902b9fb2b3e8cf82d9550a025c Mon Sep 17 00:00:00 2001 From: anton2920 Date: Tue, 6 Sep 2022 10:58:20 +0100 Subject: Refactored naming convention to 'camelCase' and changed 'System.out.println' to 'LOGGER.info' --- .../traccar/protocol/PiligrimProtocolDecoder.java | 77 +++++++++++----------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index da8991bd3..0a22e30c5 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -21,8 +21,10 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; -import net.fortuna.ical4j.model.DateTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.WebDataHandler; import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; @@ -32,13 +34,14 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; -import java.util.Arrays; import java.util.Date; import java.util.LinkedList; import java.util.List; public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { + private static final Logger LOGGER = LoggerFactory.getLogger(WebDataHandler.class); + public PiligrimProtocolDecoder(Protocol protocol) { super(protocol); } @@ -158,18 +161,18 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { sendResponse(channel, "PUSH.DO: OK"); /* Getting payload */ - ByteBuf content_stream = request.content(); - byte[] payload_bytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; - content_stream.readBytes(payload_bytes); - String payload = new String(payload_bytes); + ByteBuf contentStream = request.content(); + byte[] payloadBytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; + contentStream.readBytes(payloadBytes); + String payload = new String(payloadBytes); /* Payload structure: * &phone&message */ - String[] payload_parts = payload.split("&"); - /* System.out.println("Payload parts: " + Arrays.toString(payload_parts)); */ - String phone_number = payload_parts[1].substring(15); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phone_number); + String[] payloadParts = payload.split("&"); + /* LOGGER.info("Payload parts: " + Arrays.toString(payloadParts)); */ + String phoneNumber = payloadParts[1].substring(15); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phoneNumber); if (deviceSession == null) { return null; } @@ -177,60 +180,60 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { /* TODO: generalize this process; * TODO: use keys for flags in 'positions'. */ - String message = payload_parts[2].substring(8).replaceFirst("ALARM KEY; ", ""); - /* System.out.println("Phone number: " + phone_number); */ - /* System.out.println("Message: " + message); */ + String message = payloadParts[2].substring(8).replaceFirst("ALARM KEY; ", ""); + /* LOGGER.info("Phone number: " + phoneNumber); */ + /* LOGGER.info("Message: " + message); */ if (message.startsWith("$GPRMC")) { /* Supported message structure: * GPS NMEA Command; GSM info; Unknown; Battery voltage? * Example: $GPRMC,180752.000,A,5314.0857,N,03421.8173,E,0.00,104.74,220722,,,A,V* 29,05; GSM: 250-01 0b54-0519,1c30,3e96,3ebe,412e 25; S; Batt: 405,M */ - System.out.println("Supported message"); + LOGGER.info("Supported message"); - String[] message_parts = message.split(";"); - /* System.out.println("Message parts: " + Arrays.toString(message_parts)); */ + String[] messageParts = message.split(";"); + /* LOGGER.info("Message parts: " + Arrays.toString(messageParts)); */ /* Parsing GPS */ - String unprocessed_gps_command = message_parts[0]; + String unprocessedGpsCommand = messageParts[0]; /* Getting rid of checksum */ - String gps_command = unprocessed_gps_command.replaceFirst("A,V[*].*", ""); - /* System.out.println("GPS command: " + gps_command); */ + String gpsCommand = unprocessedGpsCommand.replaceFirst("A,V[*].*", ""); + /* LOGGER.info("GPS command: " + gpsCommand); */ - NMEA gps_parser = new NMEA(); + NMEA gpsParser = new NMEA(); - NMEA.GPSPosition gps_position = gps_parser.parse(gps_command); + NMEA.GPSPosition gpsPosition = gpsParser.parse(gpsCommand); - /* System.out.println("Time: " + gps_position.time); */ - /* System.out.println("Coordinates: " + gps_position.lat + " " + gps_position.lon); */ - /* System.out.println("Speed over ground: " + gps_position.velocity + " knots"); */ + /* LOGGER.info("Time: " + gpsPosition.time); */ + /* LOGGER.info("Coordinates: " + gpsPosition.lat + " " + gpsPosition.lon); */ + /* LOGGER.info("Speed over ground: " + gpsPosition.velocity + " knots"); */ /* Parsing other fields */ - /* String gsm_info = message_parts[1]; */ - /* String unknown = message_parts[2]; */ - String battery_info = message_parts[3].substring(7).substring(0, 3); - /* System.out.println("Battery: " + battery_info); */ + /* String gsmInfo = messageParts[1]; */ + /* String unknown = messageParts[2]; */ + String batteryInfo = messageParts[3].substring(7).substring(0, 3); + /* LOGGER.info("Battery: " + batteryInfo); */ /* Constructing response */ Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.setValid(true); - position.setLatitude(gps_position.lat); - position.setLongitude(gps_position.lon); + position.setLatitude(gpsPosition.lat); + position.setLongitude(gpsPosition.lon); position.setTime(new Date(System.currentTimeMillis())); - position.setSpeed(gps_position.velocity); - position.setCourse(gps_position.dir); - position.setAccuracy(gps_position.quality); - position.setAltitude(gps_position.altitude); - position.set(Position.KEY_BATTERY, Integer.parseInt(battery_info) / 100); + position.setSpeed(gpsPosition.velocity); + position.setCourse(gpsPosition.dir); + position.setAccuracy(gpsPosition.quality); + position.setAltitude(gpsPosition.altitude); + position.set(Position.KEY_BATTERY, Integer.parseInt(batteryInfo) / 100); - System.out.println("Supported message finish"); + LOGGER.info("Supported message finish"); return position; } else { - System.out.println("Unsupported message"); + LOGGER.info("Unsupported message"); } } -- cgit v1.2.3 From 55ac4060c38b2ea6e583cbef570f4b9ec35d8b15 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Tue, 6 Sep 2022 11:18:57 +0100 Subject: Changed regex for replacing event keys --- src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 0a22e30c5..ca6b667cd 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -172,15 +172,13 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { String[] payloadParts = payload.split("&"); /* LOGGER.info("Payload parts: " + Arrays.toString(payloadParts)); */ String phoneNumber = payloadParts[1].substring(15); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phoneNumber); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phoneNumber.substring(1)); if (deviceSession == null) { return null; } - /* TODO: generalize this process; - * TODO: use keys for flags in 'positions'. - */ - String message = payloadParts[2].substring(8).replaceFirst("ALARM KEY; ", ""); + /* TODO: use keys for flags in 'positions'. */ + String message = payloadParts[2].substring(8).replaceFirst("[A-Z]* KEY; ", ""); /* LOGGER.info("Phone number: " + phoneNumber); */ /* LOGGER.info("Message: " + message); */ -- cgit v1.2.3 From 278f8c934ec440a6472d467688bfa1c42078bbac Mon Sep 17 00:00:00 2001 From: anton2920 Date: Wed, 7 Sep 2022 09:46:48 +0100 Subject: Fixed regex for replacing event keys --- src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index ca6b667cd..6b3b35eee 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -178,7 +178,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { } /* TODO: use keys for flags in 'positions'. */ - String message = payloadParts[2].substring(8).replaceFirst("[A-Z]* KEY; ", ""); + String message = payloadParts[2].substring(8).replaceFirst("[a-zA-Z! ]*; ", ""); /* LOGGER.info("Phone number: " + phoneNumber); */ /* LOGGER.info("Message: " + message); */ @@ -210,7 +210,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { /* Parsing other fields */ /* String gsmInfo = messageParts[1]; */ /* String unknown = messageParts[2]; */ - String batteryInfo = messageParts[3].substring(7).substring(0, 3); + String batteryInfo = messageParts[messageParts.length - 1].substring(7).substring(0, 3); /* LOGGER.info("Battery: " + batteryInfo); */ /* Constructing response */ @@ -231,7 +231,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { return position; } else { - LOGGER.info("Unsupported message"); + LOGGER.error("Unsupported message"); } } -- cgit v1.2.3 From e5c73ce4fcfc67f13a9151a130783b31cef76293 Mon Sep 17 00:00:00 2001 From: anton2920 Date: Wed, 7 Sep 2022 09:47:47 +0100 Subject: Moved logger messages to debug logs --- .../traccar/protocol/PiligrimProtocolDecoder.java | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 6b3b35eee..6ca9b0795 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -170,7 +170,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { * &phone&message */ String[] payloadParts = payload.split("&"); - /* LOGGER.info("Payload parts: " + Arrays.toString(payloadParts)); */ + /* LOGGER.debug("Payload parts: " + Arrays.toString(payloadParts)); */ String phoneNumber = payloadParts[1].substring(15); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phoneNumber.substring(1)); if (deviceSession == null) { @@ -179,39 +179,39 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { /* TODO: use keys for flags in 'positions'. */ String message = payloadParts[2].substring(8).replaceFirst("[a-zA-Z! ]*; ", ""); - /* LOGGER.info("Phone number: " + phoneNumber); */ - /* LOGGER.info("Message: " + message); */ + /* LOGGER.debug("Phone number: " + phoneNumber); */ + /* LOGGER.debug("Message: " + message); */ if (message.startsWith("$GPRMC")) { /* Supported message structure: * GPS NMEA Command; GSM info; Unknown; Battery voltage? * Example: $GPRMC,180752.000,A,5314.0857,N,03421.8173,E,0.00,104.74,220722,,,A,V* 29,05; GSM: 250-01 0b54-0519,1c30,3e96,3ebe,412e 25; S; Batt: 405,M */ - LOGGER.info("Supported message"); + LOGGER.debug("Supported message"); String[] messageParts = message.split(";"); - /* LOGGER.info("Message parts: " + Arrays.toString(messageParts)); */ + /* LOGGER.debug("Message parts: " + Arrays.toString(messageParts)); */ /* Parsing GPS */ String unprocessedGpsCommand = messageParts[0]; /* Getting rid of checksum */ String gpsCommand = unprocessedGpsCommand.replaceFirst("A,V[*].*", ""); - /* LOGGER.info("GPS command: " + gpsCommand); */ + /* LOGGER.debug("GPS command: " + gpsCommand); */ NMEA gpsParser = new NMEA(); NMEA.GPSPosition gpsPosition = gpsParser.parse(gpsCommand); - /* LOGGER.info("Time: " + gpsPosition.time); */ - /* LOGGER.info("Coordinates: " + gpsPosition.lat + " " + gpsPosition.lon); */ - /* LOGGER.info("Speed over ground: " + gpsPosition.velocity + " knots"); */ + /* LOGGER.debug("Time: " + gpsPosition.time); */ + /* LOGGER.debug("Coordinates: " + gpsPosition.lat + " " + gpsPosition.lon); */ + /* LOGGER.debug("Speed over ground: " + gpsPosition.velocity + " knots"); */ /* Parsing other fields */ /* String gsmInfo = messageParts[1]; */ /* String unknown = messageParts[2]; */ String batteryInfo = messageParts[messageParts.length - 1].substring(7).substring(0, 3); - /* LOGGER.info("Battery: " + batteryInfo); */ + /* LOGGER.debug("Battery: " + batteryInfo); */ /* Constructing response */ Position position = new Position(getProtocolName()); @@ -227,7 +227,7 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { position.setAltitude(gpsPosition.altitude); position.set(Position.KEY_BATTERY, Integer.parseInt(batteryInfo) / 100); - LOGGER.info("Supported message finish"); + LOGGER.debug("Supported message finish"); return position; } else { -- cgit v1.2.3 From d4513fa86539577e24ede46d40748d8d034b025c Mon Sep 17 00:00:00 2001 From: anton2920 Date: Tue, 6 Sep 2022 10:47:37 +0100 Subject: Added support for NDTPv6 protocol --- setup/default.xml | 1 + .../org/traccar/protocol/NDTPv6FrameDecoder.java | 32 +++ .../java/org/traccar/protocol/NDTPv6Protocol.java | 26 ++ .../traccar/protocol/NDTPv6ProtocolDecoder.java | 309 +++++++++++++++++++++ .../traccar/protocol/NDTPv6ProtocolEncoder.java | 38 +++ 5 files changed, 406 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java create mode 100644 src/main/java/org/traccar/protocol/NDTPv6Protocol.java create mode 100644 src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java create mode 100644 src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java diff --git a/setup/default.xml b/setup/default.xml index 607efc35f..4f1e3ca30 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -284,5 +284,6 @@ 5239 5240 5241 + 5242 diff --git a/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java b/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java new file mode 100644 index 000000000..c869b11a4 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 NDTPv6FrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + return buf; + } + +} diff --git a/src/main/java/org/traccar/protocol/NDTPv6Protocol.java b/src/main/java/org/traccar/protocol/NDTPv6Protocol.java new file mode 100644 index 000000000..78dc11b50 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NDTPv6Protocol.java @@ -0,0 +1,26 @@ +/* + * 2020 - NDTP v6 Protocol + */ +package org.traccar.protocol; + +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class NDTPv6Protocol extends BaseProtocol { + + @Inject + public NDTPv6Protocol(Config config) { + addServer( + new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new NDTPv6ProtocolDecoder(NDTPv6Protocol.this)); + } + } + ); + } +} diff --git a/src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java b/src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java new file mode 100644 index 000000000..788afd65b --- /dev/null +++ b/src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java @@ -0,0 +1,309 @@ +/* + * 2020 - NDTP v6 Protocol Decoder + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; + +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Date; + +import org.traccar.BaseProtocolDecoder; +import org.traccar.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +public class NDTPv6ProtocolDecoder extends BaseProtocolDecoder { + + public NDTPv6ProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final byte[] SIGNATURE = {0x7E, 0x7E}; + + private static final int NPL_FLAG_CRC = 2; + private static final int NPH_RESULT_OK = 0x00000000; + private static final int NPL_TYPE_NPH = 2; + private static final int NPL_ADDRESS_SERVER = 0; + + /* common packets for all services */ + private static final int NPH_RESULT = 0; + + /* NPH service types */ + private static final int NPH_SRV_GENERIC_CONTROLS = 0; + private static final int NPH_SRV_NAVDATA = 1; + + /* NPH_SRV_GENERIC_CONTROLS packets */ + private static final int NPH_SGC_RESULT = NPH_RESULT; + private static final int NPH_SGC_CONN_REQUEST = 100; + + /* NPH_SRV_NAVDATA packets */ + private static final int NPH_SND_RESULT = NPH_RESULT; + + private static void sendResultResponse( + Channel channel, + short serviceId, + int requestId, + int nphSendResult, + int nphResult + ) { + // Формирование пакета данных + byte[] serviceIdBytes = ByteBuffer + .allocate(2) + .order(ByteOrder.LITTLE_ENDIAN) + .putShort(serviceId) + .array(); + byte[] nphSendResultBytes = ByteBuffer + .allocate(4) + .order(ByteOrder.LITTLE_ENDIAN) + .putInt(nphSendResult) + .array(); + byte[] requestIdBytes = ByteBuffer + .allocate(4) + .order(ByteOrder.LITTLE_ENDIAN) + .putInt(requestId) + .array(); + byte[] nphResultBytes = ByteBuffer + .allocate(4) + .order(ByteOrder.LITTLE_ENDIAN) + .putInt(nphResult) + .array(); + + byte[] allByteArray = new byte[serviceIdBytes.length + + requestIdBytes.length + + nphSendResultBytes.length + + nphResultBytes.length]; + + System.arraycopy(serviceIdBytes, 0, allByteArray, 0, serviceIdBytes.length); + System.arraycopy( + nphSendResultBytes, + 0, + allByteArray, + serviceIdBytes.length, + nphSendResultBytes.length + ); + System.arraycopy( + requestIdBytes, + 0, + allByteArray, + serviceIdBytes.length + nphSendResultBytes.length, + requestIdBytes.length + ); + System.arraycopy( + nphResultBytes, + 0, + allByteArray, + serviceIdBytes.length + requestIdBytes.length + nphSendResultBytes.length, + nphResultBytes.length + ); + + // ПАКЕТ ОТВЕТА КЛИЕНТУ + ByteBuf response = Unpooled.buffer(); + // NPL + response.writeBytes(SIGNATURE); + response.writeShortLE(allByteArray.length); // Размер данных + response.writeShortLE(NPL_FLAG_CRC); // Флаги + + response.writeShort( + Checksum.crc16(Checksum.CRC16_MODBUS, ByteBuffer.wrap(allByteArray)) + ); // CRC + response.writeByte(NPL_TYPE_NPH); // Тип + response.writeIntLE(NPL_ADDRESS_SERVER); // peer_address + response.writeShortLE(0); // request_id + + response.writeBytes(allByteArray); + + channel.writeAndFlush( + new NetworkMessage(response, channel.remoteAddress()) + ); + } + + private static final short MAIN_NAV_DATA = 0; + private static final short ADDITIONAL_NAV_DATA = 2; + + private void decodeData(ByteBuf buf, Position position, int dataType) { + if (dataType == NPH_SRV_NAVDATA) { + short cellType; + short cellNumber; + + cellType = buf.readUnsignedByte(); // Тип ячейки + cellNumber = buf.readUnsignedByte(); // Номер ячейки + if (cellType == MAIN_NAV_DATA && (cellNumber == 0 || cellNumber == 1)) { + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); // Значение реального времени unix + position.setLongitude(buf.readIntLE() / 10000000.0); // Долгота в градусах, умноженная на 10 000 000 + position.setLatitude(buf.readIntLE() / 10000000.0); // Широта в градусах, умноженная на 10 000 000 + + short flags = buf.readUnsignedByte(); // Достоверность навигационных данных: + // bit7 - достоверность нав. данных (1 - достоверны, 0 – нет); + // bit6 - полушарие долготы (1 – E, 0 – W); + // bit5 - полушарие широты (1 – N, 0 – S); + // bit4 - флаг работы от встроенного аккумулятора; + // bit3 – флаг первоначального включения; + // bit2 – состояние SOS (1 – SOS, 0 – нет SOS); + // bit1 – флаг тревожной информации (один из параметров + // находится в диапазоне тревоги) + position.setValid(BitUtil.check(flags, 7)); + if (BitUtil.check(flags, 1)) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 20); // Напряжение батареи, 1бит = 20мВ + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShortLE()); // Средняя скорость за период в км/ч + position.setSpeed(buf.readUnsignedShortLE() / 1.85); // Максимальная скорость за период в км/ч + + int course = buf.readUnsignedShortLE(); // Направление движения + position.setCourse(course); + + position.set(Position.KEY_DISTANCE, buf.readUnsignedShortLE()); // Пройденный путь, м + position.setAltitude(buf.readShortLE()); // Высота над уровнем моря в метрах (-18000 - +18000) + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); // Количество видимых спутников + position.set(Position.KEY_PDOP, buf.readUnsignedByte()); // PDOP + } + cellType = buf.readUnsignedByte(); // Тип ячейки + cellNumber = buf.readUnsignedByte(); // Номер ячейки + if (cellType == ADDITIONAL_NAV_DATA && cellNumber == 0) { + int analogIn1 = buf.readUnsignedShortLE(); // Значение 0 аналогового входа в 16 битном формате + //(analogIn1 - отражает напряжение на батерии для радиоборта) + int analogIn2 = buf.readUnsignedShortLE(); // Значение 1 аналогового входа в 16 битном формате + int analogIn3 = buf.readUnsignedShortLE(); // Значение 2 аналогового входа в 16 битном формате + int analogIn4 = buf.readUnsignedShortLE(); // Значение 3 аналогового входа в 16 битном формате + + buf.readUnsignedByte(); // Значение цифровых входов + buf.readUnsignedByte(); // Состояние дискретных выходов + buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 0 с предыдущей нав. отметки + buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 1 с предыдущей нав. отметки + buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 2 с предыдущей нав. отметки + buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 3 с предыдущей нав. отметки + buf.readUnsignedIntLE(); // Длина трека с момента первого включения + + position.set(Position.KEY_ANTENNA, buf.readUnsignedByte()); // Сила GSM сигнала + position.set(Position.KEY_GPS, buf.readUnsignedByte()); // Состояние GPRS подключения + position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte()); // Акселерометр - энергия + position.set(Position.KEY_POWER, buf.readUnsignedByte() * 200); // Напряжение борт. сети (1бит - 200мв) + + position.set(Position.PREFIX_ADC + 1, analogIn1 * 1); + position.set(Position.PREFIX_ADC + 2, analogIn2 * 1); + position.set(Position.PREFIX_ADC + 3, analogIn3 * 1); + position.set(Position.PREFIX_ADC + 4, analogIn4 * 1); + + // Расчет уровня батареи + // float Voltage = 5 / 4096 * analogIn1; // Вольтаж + + float batteryLevel = (analogIn1 - 3600) / 6; + + if (batteryLevel > 100) { + batteryLevel = 100; + } + if (batteryLevel < 0) { + batteryLevel = 0; + } + + position.set(Position.KEY_BATTERY_LEVEL, batteryLevel); + } + } + } + + @Override + protected Object decode( + Channel channel, + SocketAddress remoteAddress, + Object msg + ) + throws Exception { + ByteBuf buf = (ByteBuf) msg; + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + + // Заголовок NPL + buf.skipBytes(2); // Сигнатура (7e 7e) + buf.readUnsignedShortLE(); // Размер данных (nph + размер массива данных) + buf.readUnsignedShortLE(); // Флаги соединения (2 - проверять crc) + buf.readUnsignedShortLE(); // CRC (Modbus) + buf.readUnsignedByte(); // Тип пакета (nph) + buf.readUnsignedIntLE(); // Адрес участника соединения + buf.readUnsignedShortLE(); // Идентификатор NPL + + // Заголовок NPH + int serviceId = buf.readUnsignedShortLE(); // Идентификатор услуги (NPH_SRV_NAVDATA) service_id + int serviceType = buf.readUnsignedShortLE(); // Тип пакета + buf.readUnsignedShortLE(); // Флаг (1 - требуется подтверждение) NPH_FLAG_REQUEST + long requestId = buf.readUnsignedIntLE(); // Идентификатор nph + + if ( + deviceSession == null && + serviceId == NPH_SRV_GENERIC_CONTROLS && + serviceType == NPH_SGC_CONN_REQUEST + ) { // Регистрация устройства + buf.readUnsignedShortLE(); // Версия протокола NDTP (старший номер) + buf.readUnsignedShortLE(); // Версия протокола NDTP (младший номер) + buf.readUnsignedShortLE(); // Опции соединения (connection_flags) + // Определяет настройки соединения, + // которые будут использоваться после установки соединения. + // На данный момент их две: + // - бит0: шифровать пакеты (0 - нет, 1 — да) + // - бит1: рассчитывать CRC пакетов (0 - нет, 1 — да) + // - бит2: подключение симулятора (0 — подключается обычный клиент, + // 1 подключается симулятор) + // - бит3: тип алгоритма шифрования. + // - 0 - blowfish + // - 1 – ГОСТ + // - бит8: наличие поля IMEI (0 - нет, 1 — да) + // - бит9: наличие поля IMSI (0 - нет, 1 — да) + // - остальные биты не используются. + int deviceId = buf.readUnsignedShortLE(); + Position position = new Position(getProtocolName()); + deviceSession = + getDeviceSession(channel, remoteAddress, String.valueOf(deviceId)); + position.setDeviceId(deviceSession.getDeviceId()); + + if (channel != null) { + sendResultResponse( + channel, + (short) serviceId, + (int) requestId, + NPH_SND_RESULT, + NPH_RESULT_OK + ); + } + + position.set(Position.KEY_RESULT, String.valueOf(NPH_SGC_RESULT)); + position.setTime(new Date()); + getLastLocation(position, new Date()); + position.setValid(false); + + return position; + } + + if (serviceId == NPH_SRV_NAVDATA) { + deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + if (channel != null) { + sendResultResponse( + channel, + (short) serviceId, + (int) requestId, + NPH_SND_RESULT, + NPH_RESULT_OK + ); + } + + decodeData(buf, position, NPH_SRV_NAVDATA); + + return position; + } + + return null; + } +} diff --git a/src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java b/src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java new file mode 100644 index 000000000..af0dd58f9 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java @@ -0,0 +1,38 @@ +/* + * 2020 - NDTP v6 Protocol Encoder + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import java.nio.charset.StandardCharsets; +import org.traccar.BaseProtocolEncoder; +import org.traccar.Protocol; +import org.traccar.model.Command; + +public class NDTPv6ProtocolEncoder extends BaseProtocolEncoder { + + public NDTPv6ProtocolEncoder(Protocol protocol) { + super(protocol); + } + + private ByteBuf encodeCommand(String commandString) { + ByteBuf buffer = Unpooled.buffer(); + buffer.writeBytes(commandString.getBytes(StandardCharsets.US_ASCII)); + return buffer; + } + + @Override + protected Object encodeCommand(Command command) { + switch (command.getType()) { + case Command.TYPE_IDENTIFICATION: + return encodeCommand("BB+IDNT"); + case Command.TYPE_REBOOT_DEVICE: + return encodeCommand("BB+RESET"); + case Command.TYPE_POSITION_SINGLE: + return encodeCommand("BB+RRCD"); + default: + return null; + } + } +} -- cgit v1.2.3 From 596f755e19ec38cf5ce426595e2fba1a5b156338 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 8 Sep 2022 06:15:12 -0700 Subject: Attributes never null --- src/main/java/org/traccar/model/ExtendedModel.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index 0fa1856d1..ef2e3b68f 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2022 Anton Tananaev (anton@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.model; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; public class ExtendedModel extends BaseModel { @@ -31,7 +32,7 @@ public class ExtendedModel extends BaseModel { } public void setAttributes(Map attributes) { - this.attributes = attributes; + this.attributes = Objects.requireNonNullElseGet(attributes, LinkedHashMap::new); } public void set(String key, Boolean value) { -- cgit v1.2.3 From 3ac73dabfd5d9fb403c119574acd1581daa12b90 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 8 Sep 2022 06:44:45 -0700 Subject: Add Thuraya protocol support --- setup/default.xml | 1 + .../java/org/traccar/protocol/ThurayaProtocol.java | 39 +++++ .../traccar/protocol/ThurayaProtocolDecoder.java | 195 +++++++++++++++++++++ .../protocol/ThurayaProtocolDecoderTest.java | 24 +++ 4 files changed, 259 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/ThurayaProtocol.java create mode 100644 src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/ThurayaProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 607efc35f..b1417bd95 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -284,5 +284,6 @@ 5239 5240 5241 + 5242 diff --git a/src/main/java/org/traccar/protocol/ThurayaProtocol.java b/src/main/java/org/traccar/protocol/ThurayaProtocol.java new file mode 100644 index 000000000..f709a1183 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ThurayaProtocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.LengthFieldBasedFrameDecoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class ThurayaProtocol extends BaseProtocol { + + @Inject + public ThurayaProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); + pipeline.addLast(new ThurayaProtocolDecoder(ThurayaProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java new file mode 100644 index 000000000..a287ece34 --- /dev/null +++ b/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java @@ -0,0 +1,195 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.DateBuilder; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; + +public class ThurayaProtocolDecoder extends BaseProtocolDecoder { + + public ThurayaProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public static final int MSG_EVENT = 0x5101; + public static final int MSG_PERIODIC_REPORT = 0x7101; + public static final int MSG_SETTING_RESPONSE = 0x8115; + public static final int MSG_ACK = 0x9901; + + private static int checksum(ByteBuffer buf) { + int crc = 0; + while (buf.hasRemaining()) { + crc += buf.get(); + } + crc = ~crc; + crc += 1; + return crc; + } + + private void sendResponse(Channel channel, SocketAddress remoteAddress, long id, int type) { + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeCharSequence("#T", StandardCharsets.US_ASCII); + response.writeShort(15); // length + response.writeShort(MSG_ACK); + response.writeInt((int) id); + response.writeShort(type); + response.writeShort(1); // server ok + response.writeShort(checksum(response.nioBuffer())); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + } + + private void decodeLocation(ByteBuf buf, Position position) { + + position.setValid(true); + + DateBuilder dateBuilder = new DateBuilder(); + + int date = buf.readInt(); + dateBuilder.setDay(date % 100); + date /= 100; + dateBuilder.setMonth(date % 100); + date /= 100; + dateBuilder.setYear(date); + + int time = buf.readInt(); + dateBuilder.setSecond(time % 100); + time /= 100; + dateBuilder.setMinute(time % 100); + time /= 100; + dateBuilder.setHour(time); + + position.setTime(dateBuilder.getDate()); + + position.setLongitude(buf.readInt() / 1000000.0); + position.setLatitude(buf.readInt() / 1000000.0); + + int data = buf.readUnsignedShort(); + + int ignition = BitUtil.from(data, 12); + if (ignition == 1) { + position.set(Position.KEY_IGNITION, true); + } else if (ignition == 2) { + position.set(Position.KEY_IGNITION, false); + } + + position.setCourse(BitUtil.to(data, 12)); + position.setSpeed(buf.readShort()); + + position.set(Position.KEY_RPM, buf.readShort()); + + position.set("data", readString(buf)); + } + + private String decodeAlarm(int event) { + switch (event) { + case 10: + return Position.ALARM_VIBRATION; + case 11: + return Position.ALARM_OVERSPEED; + case 12: + return Position.ALARM_POWER_CUT; + case 13: + return Position.ALARM_LOW_BATTERY; + case 18: + return Position.ALARM_GPS_ANTENNA_CUT; + case 20: + return Position.ALARM_ACCELERATION; + case 21: + return Position.ALARM_BRAKING; + default: + return null; + } + } + + private String readString(ByteBuf buf) { + int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); + CharSequence value = buf.readCharSequence(endIndex - buf.readerIndex(), StandardCharsets.US_ASCII); + buf.readUnsignedByte(); // delimiter + return value.toString(); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + buf.skipBytes(2); // service + buf.readUnsignedShort(); // length + int type = buf.readUnsignedShort(); + long id = buf.readUnsignedInt(); + + sendResponse(channel, remoteAddress, id, type); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(id)); + if (deviceSession == null) { + return null; + } + + if (type == MSG_EVENT) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + decodeLocation(buf, position); + + int event = buf.readUnsignedByte(); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); + position.set("eventData", readString(buf)); + + return position; + + } else if (type == MSG_PERIODIC_REPORT) { + + List positions = new LinkedList<>(); + + int count = buf.readUnsignedByte(); + for (int i = 0; i < count; i++) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + decodeLocation(buf, position); + + positions.add(position); + + } + + return positions; + + } + + return null; + } + +} diff --git a/src/test/java/org/traccar/protocol/ThurayaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ThurayaProtocolDecoderTest.java new file mode 100644 index 000000000..90431fa24 --- /dev/null +++ b/src/test/java/org/traccar/protocol/ThurayaProtocolDecoderTest.java @@ -0,0 +1,24 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class ThurayaProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new ThurayaProtocolDecoder(null)); + + verifyPositions(decoder, binary( + "235400437101072bca3c0201348b9a00014c9f085493fc02200c5411470000000042323a300001348b9a00014d03085493ea02200c5010000000000042323a3000f2c1")); + + verifyPosition(decoder, binary( + "2354002b5101072bca3c01348b9a00013fba000000000000000010000000000042323a3000174f4e00f9de")); + + verifyNull(decoder, binary( + "235400d88115071e37d691030133342e3233362e3133302e3637000000001e56313030320030000700080102030405060708020101010101020201030103030302020000007800000078000004b000001c20050a64000015b3800015b374657374696e67003132333435360002010f28393031303539383938303134373738000043383a592c43373a592c43333a592c43323a592c43313a592c42353a592c42343a592c42323a592c42313a592c41323a592c41313a590045313a592c45373a590065746973616c61742e61650047455400322e3130d6de")); + + } + +} -- cgit v1.2.3 From 9b5654e253ed3dedfb43125a0611896dfa8fc863 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 8 Sep 2022 08:03:04 -0700 Subject: Handle unlinked notifications --- src/main/java/org/traccar/session/cache/CacheManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 6f6b648fa..64397b368 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -132,7 +132,7 @@ public class CacheManager implements BroadcastInterface { lock.readLock().lock(); var users = deviceLinks.get(deviceId).get(User.class).stream() .collect(Collectors.toUnmodifiableSet()); - return notificationUsers.get(notificationId).stream() + return notificationUsers.getOrDefault(notificationId, new LinkedList<>()).stream() .filter(user -> users.contains(user.getId())) .collect(Collectors.toUnmodifiableList()); } finally { -- cgit v1.2.3 From ff95c7dc0adf17710438f7dd2168d6ad1dd31415 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 9 Sep 2022 16:59:54 -0700 Subject: Decode G18 light sensor --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 5 +++-- src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index b65e4a4b8..885ea4bab 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -411,9 +411,12 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case 0x11: return Position.ALARM_POWER_OFF; case 0x13: + case 0x25: return Position.ALARM_TAMPERING; case 0x14: return Position.ALARM_DOOR; + case 0x23: + return Position.ALARM_FALL_DOWN; case 0x29: return Position.ALARM_ACCELERATION; case 0x30: @@ -423,8 +426,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_CORNERING; case 0x2C: return Position.ALARM_ACCIDENT; - case 0x23: - return Position.ALARM_FALL_DOWN; default: return null; } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index f3f47a104..6ab78260c 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "78782516160908063736c0006e70110442fc800000000800000000000000000300002512000473fb0d0a"), + Position.KEY_ALARM, Position.ALARM_TAMPERING); + verifyPosition(decoder, binary( "78782e2416061a103600c80275298404a0a24000184602d4023a49006f060104ed01940000086508004139765000be7d640d0a")); -- cgit v1.2.3 From 725195a271f4313255b80c99278b3a91cff799e1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 9 Sep 2022 17:35:56 -0700 Subject: Add DT700 bluetooth temperature --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 10 ++++++++++ .../java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 5393c6f74..d2b8f1fb5 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -513,6 +513,16 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_MOTION, BitUtil.check(deviceStatus, 2)); position.set("cover", BitUtil.check(deviceStatus, 3)); break; + case 0xE6: + int sensorIndex = buf.readUnsignedByte(); + buf.skipBytes(6); // mac + position.set( + Position.PREFIX_TEMP + sensorIndex, + buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + position.set( + "humidity" + sensorIndex, + buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + break; case 0xEB: if (buf.getUnsignedShort(buf.readerIndex()) > 200) { Network network = new Network(); diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 7322185d5..4ef2e25ea 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -11,6 +11,10 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "7e0200003d012291302256004800000000000c012300d2648805ff31db000e0000000022090708255503020000a70400000000ac04000002bce5020000e60b01dd34020754fe1bce3efc357e"), + Position.PREFIX_TEMP + 1, 29.06); + verifyAttribute(decoder, binary( "7E0200008201215233475100030000000000000003015A7F6106CF8CEC003D0000000021071311481901040000005630011931011AE10200755D3D0601CC0024990A7dA0032301CC002499099B2941FC01CC002499099B29430B01CC0024990A7dA0290601CC0024990A7dA015FD01CC0026220994506BFFFE157C010400000001F10C000000000000000000000000997E"), Position.KEY_ALARM, Position.ALARM_ACCELERATION); -- cgit v1.2.3 From 18807d840ce04f8052f4b1fc842f4ad2da958326 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 10 Sep 2022 16:37:53 -0700 Subject: Fix GT800 door decoding --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 7 +++++++ src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 885ea4bab..7eeee5efb 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -987,6 +987,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (subType == 0x05) { + if (buf.readableBytes() >= 6 + 1 + 6) { + DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + position.setDeviceTime(dateBuilder.getDate()); + } + int flags = buf.readUnsignedByte(); position.set(Position.KEY_DOOR, BitUtil.check(flags, 0)); position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 6ab78260c..1570dcf32 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "7979000d940516090908081c030defbd2d0d0a"), + Position.KEY_DOOR, true); + verifyAttribute(decoder, binary( "78782516160908063736c0006e70110442fc800000000800000000000000000300002512000473fb0d0a"), Position.KEY_ALARM, Position.ALARM_TAMPERING); -- cgit v1.2.3 From 1ea1c4be35687a505e21ede7b2c1e611c52f5e4a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 11 Sep 2022 15:13:55 -0700 Subject: Add Meitrack T711L test --- src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 09ab0440d..0fc51b8b6 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); + verifyPositions(decoder, binary( + "2424423233322c3836323039303035303030323831332c4343452c0400000003004400110004050006000700fe6962060800000900000a00000b00001aef044023000602d65fbcfd03173b9c0804cc76ae2a0c14ae1b000d00aa0d001c01000000014b030101003f00100004050006000700fe695f060800000900000a00000b00001aea044016000502d65fbcfd03173b9c0804cf76ae2a0c14ae1b000d03aa0d00014b030101003f00100004050006000700fe695f060800000900000a00000b00001aed044001000502d65fbcfd03173b9c0804d076ae2a0c14ae1b000d04aa0d00014b030101002a30460d0a")); + verifyAttribute(decoder, buffer( "$$F160,861412043027965,AAA,22,45.499458,-82.493581,220718171428,V,0,0,0,0,0.0,0,227940,119812,302|220|D8D6|086E1B2B,0000,0000|0000|0000|0191|0573,,,3,,002134,0,0*FA"), Position.KEY_POWER, 13.95); -- cgit v1.2.3 From b51526fdb177d3641e2780d5485586b487850874 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 11 Sep 2022 17:44:49 -0700 Subject: Fix column name --- schema/changelog-5.2.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/changelog-5.2.xml b/schema/changelog-5.2.xml index 1ac9eedc5..687024f52 100644 --- a/schema/changelog-5.2.xml +++ b/schema/changelog-5.2.xml @@ -13,7 +13,7 @@ - + -- cgit v1.2.3 From 251829fb7583c50c0bac97bc47d41bdbf63cf6c1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Sep 2022 06:01:02 -0700 Subject: Fix manager permission check --- src/main/java/org/traccar/api/security/PermissionsService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index a494c0257..ddfaaab94 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -170,8 +170,10 @@ public class PermissionsService { || before.getFixedEmail() != after.getFixedEmail()) { if (userId == after.getId()) { checkAdmin(userId); - } else { + } else if (after.getId() > 0) { checkUser(userId, after.getId()); + } else { + checkManager(userId); } } if (before.getFixedEmail() && !before.getEmail().equals(after.getEmail())) { -- cgit v1.2.3 From 30e04d7209561b7ebf6055a9170794ab9496c357 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 13 Sep 2022 06:50:44 -0700 Subject: Fix PostgreSQL blob (fix #4947) --- schema/changelog-5.3.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schema/changelog-5.3.xml b/schema/changelog-5.3.xml index 2021fe6c7..1e5a6005a 100644 --- a/schema/changelog-5.3.xml +++ b/schema/changelog-5.3.xml @@ -24,10 +24,10 @@ - + - + -- cgit v1.2.3 From 73407e12acce8061cc1aa3d18517569368707864 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Sep 2022 17:55:45 -0700 Subject: Safer Teltonika IO decoding --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 5 ++++- src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 89124cb22..ff1f52eb1 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -325,6 +325,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_GH3000) { decodeGh3000Parameter(position, id, buf, length); } else { + int index = buf.readerIndex(); boolean decoded = false; for (var entry : PARAMETERS.getOrDefault(id, new HashMap<>()).entrySet()) { if (entry.getKey() == null || model != null && entry.getKey().contains(model)) { @@ -333,7 +334,9 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { break; } } - if (!decoded) { + if (decoded) { + buf.readerIndex(index + length); + } else { position.set(Position.PREFIX_IO + id, readValue(buf, length)); } } diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 994a55109..197391d7f 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, binary( + "00000000000004258e0400000182a701b49301d5d90ab7ebe4aae101be003d12000000f7003d000e00f70100ef0000f00000500500150200c800004501000100001d00001400001600001700007157010701001d00b5000b00b60006004230400018000000cd223f00ce741700430f8900440000000d00010011ffe50012001f0013ffce000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333382e0100000053a6fb624588040001ba86064f0eae51c0fdaf4d3de500000182a701b82001d5d90ab7ebe4aae101be003d12000000f0003c000d00ef0000f00100500500150200c800004501000100001d00001400001600001700007152010701001d00b5000900b60006004217e50018000000cd223f00ce741700430f5c00440000000d00010011fed60012fd1d0013f1f2000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333352e353833332d303730373139362e323333332b3030302e3434362f00000182a701bc0801d5d90ab7ebe4aae101be003d12000000fc003d000e00ef0000f00100500500150200c800004501000100001d0000140000160000170000714d01070100fc01001d00b5000900b60006004217e50018000000cd223f00ce741700430f5c00440000000d00010011fed60012fd1d0013f1f2000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333352e353833332d303730373139362e323333332b3030302e3434362f00000182a7018d8d01d5d8ffa6ebe4a0ca01be006111000000f70001000100f70500000000000000000400003a10")); + verifyPositions(decoder, binary( "00000000000003831004000001735ace37f80000e3b9331c71e290006900e211005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005538006e00006f00007a03007d00007f5600890000fd0200fe1f09004326b00044000000b5000b00b6000600427029001800540046015d00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022a1005000000054005400000000005600015568005700000060005800000420006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3ca80000e3b08a1c71dd29006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0200fe1d09004326ac0044000000b5000b00b600060042701f001800540046015d00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022ce00500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3fc80000e3a7c01c71d7c2006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0200fe2309004326ac0044000000b5000b00b6000600427015001800540046015e00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022e700500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000000001735ace3ffa0000e3a7c01c71d7c2006900e311005100fd072e1600010100160300470300f00100150400b20000c80000ef01009000004f00005101005201005300005537006e00006f00007a03007d00007f5600890000fd0300fe2309004326ac0044000000b5000b00b6000600427015001800540046015e00ce4ec10080000f0f00f10000515400cd007404ab00d80f5022e700500000005400540000000000560001556800570000006000580000041f006800001113006d303330300071fffd8c85008700000020008800000002008a000155f5008b0000b86000040000eb85")); -- cgit v1.2.3 From 729bf987349dc9230293140139dd8ad10b7de107 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Sep 2022 18:17:28 -0700 Subject: Handle multiple DT700 sensors --- .../org/traccar/protocol/HuabaoProtocolDecoder.java | 18 ++++++++++-------- .../traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index d2b8f1fb5..0639b9dcf 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -514,14 +514,16 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set("cover", BitUtil.check(deviceStatus, 3)); break; case 0xE6: - int sensorIndex = buf.readUnsignedByte(); - buf.skipBytes(6); // mac - position.set( - Position.PREFIX_TEMP + sensorIndex, - buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); - position.set( - "humidity" + sensorIndex, - buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + while (buf.readerIndex() < endIndex) { + int sensorIndex = buf.readUnsignedByte(); + buf.skipBytes(6); // mac + position.set( + Position.PREFIX_TEMP + sensorIndex, + buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + position.set( + "humidity" + sensorIndex, + buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + } break; case 0xEB: if (buf.getUnsignedShort(buf.readerIndex()) > 200) { diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 4ef2e25ea..3661a0202 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -12,8 +12,8 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); verifyAttribute(decoder, binary( - "7e0200003d012291302256004800000000000c012300d2648805ff31db000e0000000022090708255503020000a70400000000ac04000002bce5020000e60b01dd34020754fe1bce3efc357e"), - Position.PREFIX_TEMP + 1, 29.06); + "7e0200005e01229130231209e300000000000c002300d264a305ff322300160000000022091514493503020000a70400000000ac0400000000e5020003e62c01bc5729009ca319bbff0002dd34020754fe1a83393c03bc572900ce371a6133d704dd34020751551d00fefb9a7e"), + Position.PREFIX_TEMP + 4, 29.0); verifyAttribute(decoder, binary( "7E0200008201215233475100030000000000000003015A7F6106CF8CEC003D0000000021071311481901040000005630011931011AE10200755D3D0601CC0024990A7dA0032301CC002499099B2941FC01CC002499099B29430B01CC0024990A7dA0290601CC0024990A7dA015FD01CC0026220994506BFFFE157C010400000001F10C000000000000000000000000997E"), -- cgit v1.2.3 From fd2e2183bb34951e5e9248b77e93b2e4abf1c94e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Sep 2022 18:29:28 -0700 Subject: Add Fifotrack Q2 response --- .../traccar/protocol/FifotrackProtocolDecoder.java | 26 +++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 741f4b35a..a9d77b46e 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -34,6 +34,10 @@ import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; import java.util.regex.Pattern; public class FifotrackProtocolDecoder extends BaseProtocolDecoder { @@ -78,7 +82,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { .text("$$") .number("d+,") // length .number("(d+),") // imei - .number("x+,") // index + .number("(x+),") // index .text("A03,") // type .number("(d+)?,") // alarm .number("(dd)(dd)(dd)") // date (yymmdd) @@ -137,16 +141,20 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { .number("xx") .compile(); - private void requestPhoto(Channel channel, SocketAddress socketAddress, String imei, String file) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, String imei, String content) { if (channel != null) { - String content = "1,D06," + file + "," + photo.writerIndex() + "," + Math.min(1024, photo.writableBytes()); int length = 1 + imei.length() + 1 + content.length(); String response = String.format("##%02d,%s,%s*", length, imei, content); response += Checksum.sum(response) + "\r\n"; - channel.writeAndFlush(new NetworkMessage(response, socketAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } + private void requestPhoto(Channel channel, SocketAddress remoteAddress, String imei, String file) { + String content = "1,D06," + file + "," + photo.writerIndex() + "," + Math.min(1024, photo.writableBytes()); + sendResponse(channel, remoteAddress, imei, content); + } + private String decodeAlarm(Integer alarm) { if (alarm != null) { switch (alarm) { @@ -200,11 +208,14 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { return null; } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + String imei = parser.next(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; } + String index = parser.next(); + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -243,6 +254,11 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(network); + DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + String response = index + ",A03," + dateFormat.format(new Date()); + sendResponse(channel, remoteAddress, imei, response); + return position; } -- cgit v1.2.3 From 7aa230b9ddcd5540e7ff9c9b3d9bcf5119175c46 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Sat, 17 Sep 2022 20:46:40 +0100 Subject: Xexun2 Encoder update --- src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index c315cab30..8f3fa5672 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -40,7 +40,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { buf.writeShort(Xexun2ProtocolDecoder.MSG_COMMAND); buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); - buf.writeShort(message.capacity()); + buf.writeShort(message.readableBytes()); buf.writeShort(Checksum.ip(message.nioBuffer())); buf.writeBytes(message); buf.writeShort(Xexun2ProtocolDecoder.FLAG); -- cgit v1.2.3 From 79ecdf701ce5db5505c366bafe4f04e4d565ec7d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 17 Sep 2022 16:57:29 -0700 Subject: Fix temperature decoding --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 9122eb362..eb8c1c466 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -293,7 +293,9 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 51: case 52: value = buf.readByte(); - position.set(Position.PREFIX_TEMP + (j + 2 - 45), (value != 0x80) ? value : null); + position.set( + Position.PREFIX_TEMP + (j + 2 - 45), + (value != (byte) 0x80) ? value : null); break; default: buf.skipBytes(getItemLength(j + 1)); -- cgit v1.2.3 From 3a6219d8cc2a014a78d53f9ca9695558ffd72926 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 17 Sep 2022 16:58:10 -0700 Subject: Remove unnecessary assignment --- src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index eb8c1c466..20e10cdcd 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -196,7 +196,7 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { for (int j = 0; j < bits.length(); j++) { if (bits.get(j)) { - int value = 0; + int value; switch (j + 1) { case 1: -- cgit v1.2.3 From 2d36cb5e0bbad23064d75f1f9364094b3e2fefa5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 17 Sep 2022 17:00:48 -0700 Subject: Some Navis improvements --- src/main/java/org/traccar/protocol/NavisProtocolDecoder.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java index 53631bd4e..77158b315 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; -import org.traccar.helper.Checksum.Algorithm; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -591,10 +590,8 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { private void sendFlexReply(Channel channel, ByteBuf data) { if (channel != null) { - ByteBuf cs = Unpooled.buffer(1); - cs.writeByte(Checksum.crc8(new Algorithm(8, 0x31, 0xFF, false, false, 0x00), data.nioBuffer())); - - channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(data, cs), channel.remoteAddress())); + data.writeByte(Checksum.crc8(Checksum.CRC8_EGTS, data.nioBuffer())); + channel.writeAndFlush(new NetworkMessage(data, channel.remoteAddress())); } } -- cgit v1.2.3 From 6864e0a0a067f432bead08331404d4b141959a64 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 17 Sep 2022 17:26:52 -0700 Subject: Navtelecom fuel temperature --- .../java/org/traccar/protocol/NavtelecomProtocolDecoder.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java index 20e10cdcd..08b1a8d0f 100644 --- a/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavtelecomProtocolDecoder.java @@ -278,11 +278,11 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { case 42: case 43: value = buf.readUnsignedShortLE(); - position.set("rs485Fuel" + (j + 2 - 38), (value < 65500) ? value : null); + position.set("fuel" + (j + 2 - 38), (value < 65500) ? value : null); break; case 44: value = buf.readUnsignedShortLE(); - position.set("rs232Fuel", (value < 65500) ? value : null); + position.set(Position.KEY_FUEL_LEVEL, (value < 65500) ? value : null); break; case 45: case 46: @@ -297,6 +297,14 @@ public class NavtelecomProtocolDecoder extends BaseProtocolDecoder { Position.PREFIX_TEMP + (j + 2 - 45), (value != (byte) 0x80) ? value : null); break; + case 78: + case 79: + case 80: + case 81: + case 82: + case 83: + position.set("fuelTemp" + (j + 2 - 78), (int) buf.readByte()); + break; default: buf.skipBytes(getItemLength(j + 1)); break; -- cgit v1.2.3 From 43e04167d35c9f68eb5850f6e7e9f2723400957f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 18 Sep 2022 09:26:22 -0700 Subject: Decode TAT100 cell info --- .../traccar/protocol/TeltonikaProtocolDecoder.java | 44 +++++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index ff1f52eb1..4671a1088 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -342,16 +342,40 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeNetwork(Position position) { - Integer cid = (Integer) position.getAttributes().remove("cid"); - Integer lac = (Integer) position.getAttributes().remove("lac"); - if (cid != null && lac != null) { - CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); - long operator = position.getInteger(Position.KEY_OPERATOR); - if (operator >= 1000) { - cellTower.setOperator(operator); + private void decodeCell( + Position position, Network network, String mncKey, String lacKey, String cidKey, String rssiKey) { + if (position.hasAttribute(mncKey) && position.hasAttribute(lacKey) && position.hasAttribute(cidKey)) { + CellTower cellTower = CellTower.from( + getConfig().getInteger(Keys.GEOLOCATION_MCC), + (Integer) position.getAttributes().remove(mncKey), + (Integer) position.getAttributes().remove(lacKey), + (Integer) position.getAttributes().remove(cidKey)); + cellTower.setSignalStrength((Integer) position.getAttributes().remove(rssiKey)); + network.addCellTower(cellTower); + } + } + + private void decodeNetwork(Position position, String model) { + if ("TAT100".equals(model)) { + Network network = new Network(); + decodeCell(position, network, "io1200", "io287", "io288", "io289"); + decodeCell(position, network, "io1201", "io290", "io291", "io292"); + decodeCell(position, network, "io1202", "io293", "io294", "io295"); + decodeCell(position, network, "io1203", "io296", "io297", "io298"); + if (network.getCellTowers() != null) { + position.setNetwork(network); + } + } else { + Integer cid = (Integer) position.getAttributes().remove("cid"); + Integer lac = (Integer) position.getAttributes().remove("lac"); + if (cid != null && lac != null) { + CellTower cellTower = CellTower.fromLacCid(getConfig(), lac, cid); + long operator = position.getInteger(Position.KEY_OPERATOR); + if (operator >= 1000) { + cellTower.setOperator(operator); + } + position.setNetwork(new Network(cellTower)); } - position.setNetwork(new Network(cellTower)); } } @@ -545,7 +569,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - decodeNetwork(position); + decodeNetwork(position, model); } -- cgit v1.2.3 From 4de8efe1ef0810af492c161bfc1d3200958d75d8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 18 Sep 2022 10:01:28 -0700 Subject: Refactor M-5000/10000 decoding --- src/main/java/org/traccar/helper/NMEA.java | 126 --------------------- .../traccar/protocol/PiligrimProtocolDecoder.java | 125 ++++++++------------ .../protocol/PiligrimProtocolDecoderTest.java | 4 + 3 files changed, 52 insertions(+), 203 deletions(-) delete mode 100644 src/main/java/org/traccar/helper/NMEA.java diff --git a/src/main/java/org/traccar/helper/NMEA.java b/src/main/java/org/traccar/helper/NMEA.java deleted file mode 100644 index cae47a8f6..000000000 --- a/src/main/java/org/traccar/helper/NMEA.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.traccar.helper; - -import java.util.HashMap; -import java.util.Map; - - -public class NMEA { - - // fucking java interfaces - interface SentenceParser { - public boolean parse(String[] tokens, GPSPosition position); - } - - // utils - static float Latitude2Decimal(String lat, String NS) { - float med = Float.parseFloat(lat.substring(2)) / 60.0f; - med += Float.parseFloat(lat.substring(0, 2)); - if (NS.startsWith("S")) { - med = -med; - } - return med; - } - - static float Longitude2Decimal(String lon, String WE) { - float med = Float.parseFloat(lon.substring(3)) / 60.0f; - med += Float.parseFloat(lon.substring(0, 3)); - if (WE.startsWith("W")) { - med = -med; - } - return med; - } - - // parsers - class GPGGA implements SentenceParser { - public boolean parse(String[] tokens, GPSPosition position) { - position.time = Float.parseFloat(tokens[1]); - position.lat = Latitude2Decimal(tokens[2], tokens[3]); - position.lon = Longitude2Decimal(tokens[4], tokens[5]); - position.quality = Integer.parseInt(tokens[6]); - position.altitude = Float.parseFloat(tokens[9]); - return true; - } - } - - class GPGGL implements SentenceParser { - public boolean parse(String[] tokens, GPSPosition position) { - position.lat = Latitude2Decimal(tokens[1], tokens[2]); - position.lon = Longitude2Decimal(tokens[3], tokens[4]); - position.time = Float.parseFloat(tokens[5]); - return true; - } - } - - class GPRMC implements SentenceParser { - public boolean parse(String[] tokens, GPSPosition position) { - position.time = Float.parseFloat(tokens[1]); - position.lat = Latitude2Decimal(tokens[3], tokens[4]); - position.lon = Longitude2Decimal(tokens[5], tokens[6]); - position.velocity = Float.parseFloat(tokens[7]); - position.dir = Float.parseFloat(tokens[8]); - return true; - } - } - - class GPVTG implements SentenceParser { - public boolean parse(String[] tokens, GPSPosition position) { - position.dir = Float.parseFloat(tokens[3]); - return true; - } - } - - class GPRMZ implements SentenceParser { - public boolean parse(String[] tokens, GPSPosition position) { - position.altitude = Float.parseFloat(tokens[1]); - return true; - } - } - - public class GPSPosition { - public float time = 0.0f; - public float lat = 0.0f; - public float lon = 0.0f; - public boolean fixed = false; - public int quality = 0; - public float dir = 0.0f; - public float altitude = 0.0f; - public float velocity = 0.0f; - - public void updatefix() { - fixed = quality > 0; - } - - public String toString() { - return String.format("POSITION: lat: %f, lon: %f, time: %f, Q: %d, dir: %f, alt: %f, vel: %f", lat, lon, time, quality, dir, altitude, velocity); - } - } - - GPSPosition position = new GPSPosition(); - - private static final Map sentenceParsers = new HashMap(); - - public NMEA() { - sentenceParsers.put("GPGGA", new GPGGA()); - sentenceParsers.put("GPGGL", new GPGGL()); - sentenceParsers.put("GPRMC", new GPRMC()); - sentenceParsers.put("GPRMZ", new GPRMZ()); - //only really good GPS devices have this sentence but ... - sentenceParsers.put("GPVTG", new GPVTG()); - } - - public GPSPosition parse(String line) { - - if (line.startsWith("$")) { - String nmea = line.substring(1); - String[] tokens = nmea.split(","); - String type = tokens[0]; - //TODO check crc - if (sentenceParsers.containsKey(type)) { - sentenceParsers.get(type).parse(tokens, position); - } - position.updatefix(); - } - - return position; - } -} diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java index 6ca9b0795..34c879cb8 100644 --- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2022 Anton Tananaev (anton@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,27 +21,23 @@ import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.BaseHttpProtocolDecoder; -import org.traccar.WebDataHandler; -import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; -import org.traccar.helper.NMEA; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; +import org.traccar.session.DeviceSession; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; -import java.util.Date; import java.util.LinkedList; import java.util.List; +import java.util.regex.Pattern; public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { - private static final Logger LOGGER = LoggerFactory.getLogger(WebDataHandler.class); - public PiligrimProtocolDecoder(Protocol protocol) { super(protocol); } @@ -54,6 +50,21 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { public static final int MSG_GPS_SENSORS = 0xF2; public static final int MSG_EVENTS = 0xF3; + private static final Pattern PATTERN = new PatternBuilder() + .expression("[^$]+") + .text("$GPRMC,") + .number("(dd)(dd)(dd).d+,") // time (hhmmss) + .expression("([AV]),") // validity + .number("(dd)(dd.d+),") // latitude + .expression("([NS]),") + .number("(d{2,3})(dd.d+),") // longitude + .expression("([EW]),") + .number("(d+.d+),") // speed + .number("(d+.d+),") // course + .number("(dd)(dd)(dd),") // date (ddmmyy) + .any() + .compile(); + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -157,82 +168,42 @@ public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder { } return positions; + } else if (uri.startsWith("/push.do")) { + sendResponse(channel, "PUSH.DO: OK"); - /* Getting payload */ - ByteBuf contentStream = request.content(); - byte[] payloadBytes = new byte[Integer.parseInt(request.headers().get("Content-Length"))]; - contentStream.readBytes(payloadBytes); - String payload = new String(payloadBytes); - - /* Payload structure: - * &phone&message - */ - String[] payloadParts = payload.split("&"); - /* LOGGER.debug("Payload parts: " + Arrays.toString(payloadParts)); */ - String phoneNumber = payloadParts[1].substring(15); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phoneNumber.substring(1)); + String sentence = request.content().toString(StandardCharsets.US_ASCII); + + String[] parts = sentence.split("&"); + String phone = parts[1].substring(16); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, phone); if (deviceSession == null) { return null; } - /* TODO: use keys for flags in 'positions'. */ - String message = payloadParts[2].substring(8).replaceFirst("[a-zA-Z! ]*; ", ""); - /* LOGGER.debug("Phone number: " + phoneNumber); */ - /* LOGGER.debug("Message: " + message); */ - - if (message.startsWith("$GPRMC")) { - /* Supported message structure: - * GPS NMEA Command; GSM info; Unknown; Battery voltage? - * Example: $GPRMC,180752.000,A,5314.0857,N,03421.8173,E,0.00,104.74,220722,,,A,V* 29,05; GSM: 250-01 0b54-0519,1c30,3e96,3ebe,412e 25; S; Batt: 405,M - */ - LOGGER.debug("Supported message"); - - String[] messageParts = message.split(";"); - /* LOGGER.debug("Message parts: " + Arrays.toString(messageParts)); */ - - /* Parsing GPS */ - String unprocessedGpsCommand = messageParts[0]; - - /* Getting rid of checksum */ - String gpsCommand = unprocessedGpsCommand.replaceFirst("A,V[*].*", ""); - /* LOGGER.debug("GPS command: " + gpsCommand); */ - - NMEA gpsParser = new NMEA(); - - NMEA.GPSPosition gpsPosition = gpsParser.parse(gpsCommand); - - /* LOGGER.debug("Time: " + gpsPosition.time); */ - /* LOGGER.debug("Coordinates: " + gpsPosition.lat + " " + gpsPosition.lon); */ - /* LOGGER.debug("Speed over ground: " + gpsPosition.velocity + " knots"); */ - - /* Parsing other fields */ - /* String gsmInfo = messageParts[1]; */ - /* String unknown = messageParts[2]; */ - String batteryInfo = messageParts[messageParts.length - 1].substring(7).substring(0, 3); - /* LOGGER.debug("Battery: " + batteryInfo); */ - - /* Constructing response */ - Position position = new Position(getProtocolName()); - - position.setDeviceId(deviceSession.getDeviceId()); - position.setValid(true); - position.setLatitude(gpsPosition.lat); - position.setLongitude(gpsPosition.lon); - position.setTime(new Date(System.currentTimeMillis())); - position.setSpeed(gpsPosition.velocity); - position.setCourse(gpsPosition.dir); - position.setAccuracy(gpsPosition.quality); - position.setAltitude(gpsPosition.altitude); - position.set(Position.KEY_BATTERY, Integer.parseInt(batteryInfo) / 100); - - LOGGER.debug("Supported message finish"); - - return position; - } else { - LOGGER.error("Unsupported message"); + Parser parser = new Parser(PATTERN, parts[2]); + if (!parser.matches()) { + return null; } + + 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()); + position.setCourse(parser.nextDouble()); + + dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + return position; + } return null; diff --git a/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java index 475ac0125..0dd00462d 100644 --- a/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/PiligrimProtocolDecoderTest.java @@ -15,6 +15,10 @@ public class PiligrimProtocolDecoderTest extends ProtocolTest { "/bingps?imei=868204005544720&csq=18&vout=00&vin=4050&dataid=00000000", binary("fff2200d4110061a32354f3422310062000a0005173b0000a101000300005e00fff2200d4110100932354f2b22310042000b000e173b00009f01000700006000"))); + verifyPosition(decoder, request(HttpMethod.POST, + "/push.do", + buffer("&phoneNumber=%2B+78000000000&message=ALARM KEY; $GPRMC,180752.000,A,5314.0857,N,03421.8173,E,0.00,104.74,220722,,,A,V* 29,05; GSM: 250-01 0b54-0519,1c30,3e96,3ebe,412e 25; S; Batt: 405,M"))); + } } -- cgit v1.2.3 From 8532bffcec8e239c6699845e09e63da927f51d9a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 18 Sep 2022 10:47:58 -0700 Subject: Refactor NDTPv6 protocol --- .../org/traccar/protocol/NDTPv6FrameDecoder.java | 32 --- .../java/org/traccar/protocol/NDTPv6Protocol.java | 26 -- .../traccar/protocol/NDTPv6ProtocolDecoder.java | 309 --------------------- .../traccar/protocol/NDTPv6ProtocolEncoder.java | 38 --- .../org/traccar/protocol/NdtpV6FrameDecoder.java | 32 +++ .../java/org/traccar/protocol/NdtpV6Protocol.java | 39 +++ .../traccar/protocol/NdtpV6ProtocolDecoder.java | 203 ++++++++++++++ .../traccar/protocol/NdtpV6ProtocolEncoder.java | 42 +++ 8 files changed, 316 insertions(+), 405 deletions(-) delete mode 100644 src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java delete mode 100644 src/main/java/org/traccar/protocol/NDTPv6Protocol.java delete mode 100644 src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java delete mode 100644 src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java create mode 100644 src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java create mode 100644 src/main/java/org/traccar/protocol/NdtpV6Protocol.java create mode 100644 src/main/java/org/traccar/protocol/NdtpV6ProtocolDecoder.java create mode 100644 src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java diff --git a/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java b/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java deleted file mode 100644 index c869b11a4..000000000 --- a/src/main/java/org/traccar/protocol/NDTPv6FrameDecoder.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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 NDTPv6FrameDecoder extends BaseFrameDecoder { - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { - - return buf; - } - -} diff --git a/src/main/java/org/traccar/protocol/NDTPv6Protocol.java b/src/main/java/org/traccar/protocol/NDTPv6Protocol.java deleted file mode 100644 index 78dc11b50..000000000 --- a/src/main/java/org/traccar/protocol/NDTPv6Protocol.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 2020 - NDTP v6 Protocol - */ -package org.traccar.protocol; - -import org.traccar.BaseProtocol; -import org.traccar.PipelineBuilder; -import org.traccar.TrackerServer; -import org.traccar.config.Config; - -import javax.inject.Inject; - -public class NDTPv6Protocol extends BaseProtocol { - - @Inject - public NDTPv6Protocol(Config config) { - addServer( - new TrackerServer(config, getName(), false) { - @Override - protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { - pipeline.addLast(new NDTPv6ProtocolDecoder(NDTPv6Protocol.this)); - } - } - ); - } -} diff --git a/src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java b/src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java deleted file mode 100644 index 788afd65b..000000000 --- a/src/main/java/org/traccar/protocol/NDTPv6ProtocolDecoder.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * 2020 - NDTP v6 Protocol Decoder - */ -package org.traccar.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.Channel; - -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Date; - -import org.traccar.BaseProtocolDecoder; -import org.traccar.NetworkMessage; -import org.traccar.Protocol; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Checksum; -import org.traccar.model.Position; -import org.traccar.session.DeviceSession; - -public class NDTPv6ProtocolDecoder extends BaseProtocolDecoder { - - public NDTPv6ProtocolDecoder(Protocol protocol) { - super(protocol); - } - - private static final byte[] SIGNATURE = {0x7E, 0x7E}; - - private static final int NPL_FLAG_CRC = 2; - private static final int NPH_RESULT_OK = 0x00000000; - private static final int NPL_TYPE_NPH = 2; - private static final int NPL_ADDRESS_SERVER = 0; - - /* common packets for all services */ - private static final int NPH_RESULT = 0; - - /* NPH service types */ - private static final int NPH_SRV_GENERIC_CONTROLS = 0; - private static final int NPH_SRV_NAVDATA = 1; - - /* NPH_SRV_GENERIC_CONTROLS packets */ - private static final int NPH_SGC_RESULT = NPH_RESULT; - private static final int NPH_SGC_CONN_REQUEST = 100; - - /* NPH_SRV_NAVDATA packets */ - private static final int NPH_SND_RESULT = NPH_RESULT; - - private static void sendResultResponse( - Channel channel, - short serviceId, - int requestId, - int nphSendResult, - int nphResult - ) { - // Формирование пакета данных - byte[] serviceIdBytes = ByteBuffer - .allocate(2) - .order(ByteOrder.LITTLE_ENDIAN) - .putShort(serviceId) - .array(); - byte[] nphSendResultBytes = ByteBuffer - .allocate(4) - .order(ByteOrder.LITTLE_ENDIAN) - .putInt(nphSendResult) - .array(); - byte[] requestIdBytes = ByteBuffer - .allocate(4) - .order(ByteOrder.LITTLE_ENDIAN) - .putInt(requestId) - .array(); - byte[] nphResultBytes = ByteBuffer - .allocate(4) - .order(ByteOrder.LITTLE_ENDIAN) - .putInt(nphResult) - .array(); - - byte[] allByteArray = new byte[serviceIdBytes.length + - requestIdBytes.length + - nphSendResultBytes.length + - nphResultBytes.length]; - - System.arraycopy(serviceIdBytes, 0, allByteArray, 0, serviceIdBytes.length); - System.arraycopy( - nphSendResultBytes, - 0, - allByteArray, - serviceIdBytes.length, - nphSendResultBytes.length - ); - System.arraycopy( - requestIdBytes, - 0, - allByteArray, - serviceIdBytes.length + nphSendResultBytes.length, - requestIdBytes.length - ); - System.arraycopy( - nphResultBytes, - 0, - allByteArray, - serviceIdBytes.length + requestIdBytes.length + nphSendResultBytes.length, - nphResultBytes.length - ); - - // ПАКЕТ ОТВЕТА КЛИЕНТУ - ByteBuf response = Unpooled.buffer(); - // NPL - response.writeBytes(SIGNATURE); - response.writeShortLE(allByteArray.length); // Размер данных - response.writeShortLE(NPL_FLAG_CRC); // Флаги - - response.writeShort( - Checksum.crc16(Checksum.CRC16_MODBUS, ByteBuffer.wrap(allByteArray)) - ); // CRC - response.writeByte(NPL_TYPE_NPH); // Тип - response.writeIntLE(NPL_ADDRESS_SERVER); // peer_address - response.writeShortLE(0); // request_id - - response.writeBytes(allByteArray); - - channel.writeAndFlush( - new NetworkMessage(response, channel.remoteAddress()) - ); - } - - private static final short MAIN_NAV_DATA = 0; - private static final short ADDITIONAL_NAV_DATA = 2; - - private void decodeData(ByteBuf buf, Position position, int dataType) { - if (dataType == NPH_SRV_NAVDATA) { - short cellType; - short cellNumber; - - cellType = buf.readUnsignedByte(); // Тип ячейки - cellNumber = buf.readUnsignedByte(); // Номер ячейки - if (cellType == MAIN_NAV_DATA && (cellNumber == 0 || cellNumber == 1)) { - position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); // Значение реального времени unix - position.setLongitude(buf.readIntLE() / 10000000.0); // Долгота в градусах, умноженная на 10 000 000 - position.setLatitude(buf.readIntLE() / 10000000.0); // Широта в градусах, умноженная на 10 000 000 - - short flags = buf.readUnsignedByte(); // Достоверность навигационных данных: - // bit7 - достоверность нав. данных (1 - достоверны, 0 – нет); - // bit6 - полушарие долготы (1 – E, 0 – W); - // bit5 - полушарие широты (1 – N, 0 – S); - // bit4 - флаг работы от встроенного аккумулятора; - // bit3 – флаг первоначального включения; - // bit2 – состояние SOS (1 – SOS, 0 – нет SOS); - // bit1 – флаг тревожной информации (один из параметров - // находится в диапазоне тревоги) - position.setValid(BitUtil.check(flags, 7)); - if (BitUtil.check(flags, 1)) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } - position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 20); // Напряжение батареи, 1бит = 20мВ - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShortLE()); // Средняя скорость за период в км/ч - position.setSpeed(buf.readUnsignedShortLE() / 1.85); // Максимальная скорость за период в км/ч - - int course = buf.readUnsignedShortLE(); // Направление движения - position.setCourse(course); - - position.set(Position.KEY_DISTANCE, buf.readUnsignedShortLE()); // Пройденный путь, м - position.setAltitude(buf.readShortLE()); // Высота над уровнем моря в метрах (-18000 - +18000) - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); // Количество видимых спутников - position.set(Position.KEY_PDOP, buf.readUnsignedByte()); // PDOP - } - cellType = buf.readUnsignedByte(); // Тип ячейки - cellNumber = buf.readUnsignedByte(); // Номер ячейки - if (cellType == ADDITIONAL_NAV_DATA && cellNumber == 0) { - int analogIn1 = buf.readUnsignedShortLE(); // Значение 0 аналогового входа в 16 битном формате - //(analogIn1 - отражает напряжение на батерии для радиоборта) - int analogIn2 = buf.readUnsignedShortLE(); // Значение 1 аналогового входа в 16 битном формате - int analogIn3 = buf.readUnsignedShortLE(); // Значение 2 аналогового входа в 16 битном формате - int analogIn4 = buf.readUnsignedShortLE(); // Значение 3 аналогового входа в 16 битном формате - - buf.readUnsignedByte(); // Значение цифровых входов - buf.readUnsignedByte(); // Состояние дискретных выходов - buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 0 с предыдущей нав. отметки - buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 1 с предыдущей нав. отметки - buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 2 с предыдущей нав. отметки - buf.readUnsignedShortLE(); // Количество импульсов на дискретном входе 3 с предыдущей нав. отметки - buf.readUnsignedIntLE(); // Длина трека с момента первого включения - - position.set(Position.KEY_ANTENNA, buf.readUnsignedByte()); // Сила GSM сигнала - position.set(Position.KEY_GPS, buf.readUnsignedByte()); // Состояние GPRS подключения - position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte()); // Акселерометр - энергия - position.set(Position.KEY_POWER, buf.readUnsignedByte() * 200); // Напряжение борт. сети (1бит - 200мв) - - position.set(Position.PREFIX_ADC + 1, analogIn1 * 1); - position.set(Position.PREFIX_ADC + 2, analogIn2 * 1); - position.set(Position.PREFIX_ADC + 3, analogIn3 * 1); - position.set(Position.PREFIX_ADC + 4, analogIn4 * 1); - - // Расчет уровня батареи - // float Voltage = 5 / 4096 * analogIn1; // Вольтаж - - float batteryLevel = (analogIn1 - 3600) / 6; - - if (batteryLevel > 100) { - batteryLevel = 100; - } - if (batteryLevel < 0) { - batteryLevel = 0; - } - - position.set(Position.KEY_BATTERY_LEVEL, batteryLevel); - } - } - } - - @Override - protected Object decode( - Channel channel, - SocketAddress remoteAddress, - Object msg - ) - throws Exception { - ByteBuf buf = (ByteBuf) msg; - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - - // Заголовок NPL - buf.skipBytes(2); // Сигнатура (7e 7e) - buf.readUnsignedShortLE(); // Размер данных (nph + размер массива данных) - buf.readUnsignedShortLE(); // Флаги соединения (2 - проверять crc) - buf.readUnsignedShortLE(); // CRC (Modbus) - buf.readUnsignedByte(); // Тип пакета (nph) - buf.readUnsignedIntLE(); // Адрес участника соединения - buf.readUnsignedShortLE(); // Идентификатор NPL - - // Заголовок NPH - int serviceId = buf.readUnsignedShortLE(); // Идентификатор услуги (NPH_SRV_NAVDATA) service_id - int serviceType = buf.readUnsignedShortLE(); // Тип пакета - buf.readUnsignedShortLE(); // Флаг (1 - требуется подтверждение) NPH_FLAG_REQUEST - long requestId = buf.readUnsignedIntLE(); // Идентификатор nph - - if ( - deviceSession == null && - serviceId == NPH_SRV_GENERIC_CONTROLS && - serviceType == NPH_SGC_CONN_REQUEST - ) { // Регистрация устройства - buf.readUnsignedShortLE(); // Версия протокола NDTP (старший номер) - buf.readUnsignedShortLE(); // Версия протокола NDTP (младший номер) - buf.readUnsignedShortLE(); // Опции соединения (connection_flags) - // Определяет настройки соединения, - // которые будут использоваться после установки соединения. - // На данный момент их две: - // - бит0: шифровать пакеты (0 - нет, 1 — да) - // - бит1: рассчитывать CRC пакетов (0 - нет, 1 — да) - // - бит2: подключение симулятора (0 — подключается обычный клиент, - // 1 подключается симулятор) - // - бит3: тип алгоритма шифрования. - // - 0 - blowfish - // - 1 – ГОСТ - // - бит8: наличие поля IMEI (0 - нет, 1 — да) - // - бит9: наличие поля IMSI (0 - нет, 1 — да) - // - остальные биты не используются. - int deviceId = buf.readUnsignedShortLE(); - Position position = new Position(getProtocolName()); - deviceSession = - getDeviceSession(channel, remoteAddress, String.valueOf(deviceId)); - position.setDeviceId(deviceSession.getDeviceId()); - - if (channel != null) { - sendResultResponse( - channel, - (short) serviceId, - (int) requestId, - NPH_SND_RESULT, - NPH_RESULT_OK - ); - } - - position.set(Position.KEY_RESULT, String.valueOf(NPH_SGC_RESULT)); - position.setTime(new Date()); - getLastLocation(position, new Date()); - position.setValid(false); - - return position; - } - - if (serviceId == NPH_SRV_NAVDATA) { - deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - if (channel != null) { - sendResultResponse( - channel, - (short) serviceId, - (int) requestId, - NPH_SND_RESULT, - NPH_RESULT_OK - ); - } - - decodeData(buf, position, NPH_SRV_NAVDATA); - - return position; - } - - return null; - } -} diff --git a/src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java b/src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java deleted file mode 100644 index af0dd58f9..000000000 --- a/src/main/java/org/traccar/protocol/NDTPv6ProtocolEncoder.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 2020 - NDTP v6 Protocol Encoder - */ -package org.traccar.protocol; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import java.nio.charset.StandardCharsets; -import org.traccar.BaseProtocolEncoder; -import org.traccar.Protocol; -import org.traccar.model.Command; - -public class NDTPv6ProtocolEncoder extends BaseProtocolEncoder { - - public NDTPv6ProtocolEncoder(Protocol protocol) { - super(protocol); - } - - private ByteBuf encodeCommand(String commandString) { - ByteBuf buffer = Unpooled.buffer(); - buffer.writeBytes(commandString.getBytes(StandardCharsets.US_ASCII)); - return buffer; - } - - @Override - protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_IDENTIFICATION: - return encodeCommand("BB+IDNT"); - case Command.TYPE_REBOOT_DEVICE: - return encodeCommand("BB+RESET"); - case Command.TYPE_POSITION_SINGLE: - return encodeCommand("BB+RRCD"); - default: - return null; - } - } -} diff --git a/src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java b/src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java new file mode 100644 index 000000000..5b610013a --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6FrameDecoder.java @@ -0,0 +1,32 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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 NdtpV6FrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + return buf; + } + +} diff --git a/src/main/java/org/traccar/protocol/NdtpV6Protocol.java b/src/main/java/org/traccar/protocol/NdtpV6Protocol.java new file mode 100644 index 000000000..ce0dbbef2 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6Protocol.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class NdtpV6Protocol extends BaseProtocol { + + @Inject + public NdtpV6Protocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new NdtpV6ProtocolDecoder(NdtpV6Protocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/NdtpV6ProtocolDecoder.java b/src/main/java/org/traccar/protocol/NdtpV6ProtocolDecoder.java new file mode 100644 index 000000000..35cb0bae8 --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6ProtocolDecoder.java @@ -0,0 +1,203 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.NetworkMessage; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import java.net.SocketAddress; +import java.util.Date; + +public class NdtpV6ProtocolDecoder extends BaseProtocolDecoder { + + public NdtpV6ProtocolDecoder(Protocol protocol) { + super(protocol); + } + + private static final byte[] SIGNATURE = {0x7E, 0x7E}; + + private static final int NPL_FLAG_CRC = 2; + private static final int NPH_RESULT_OK = 0x00000000; + private static final int NPL_TYPE_NPH = 2; + private static final int NPL_ADDRESS_SERVER = 0; + + private static final int NPH_RESULT = 0; + + private static final int NPH_SRV_GENERIC_CONTROLS = 0; + private static final int NPH_SRV_NAVDATA = 1; + + private static final int NPH_SGC_RESULT = NPH_RESULT; + private static final int NPH_SGC_CONN_REQUEST = 100; + + private static final int NPH_SND_RESULT = NPH_RESULT; + + private void sendResponse( + Channel channel, int serviceId, long requestId) { + + ByteBuf content = Unpooled.buffer(); + content.writeShortLE(serviceId); + content.writeIntLE(NPH_SND_RESULT); + content.writeIntLE((int) requestId); + content.writeIntLE(NPH_RESULT_OK); + + ByteBuf response = Unpooled.buffer(); + response.writeBytes(SIGNATURE); + response.writeShortLE(content.readableBytes()); + response.writeShortLE(NPL_FLAG_CRC); // flags + response.writeShort(Checksum.crc16(Checksum.CRC16_MODBUS, content.nioBuffer())); + response.writeByte(NPL_TYPE_NPH); // type + response.writeIntLE(NPL_ADDRESS_SERVER); // peer address + response.writeShortLE(0); // request id + response.writeBytes(content); + content.release(); + + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + } + + private static final short MAIN_NAV_DATA = 0; + private static final short ADDITIONAL_NAV_DATA = 2; + + private void decodeData(ByteBuf buf, Position position) { + + short itemType; + short itemIndex; + + itemType = buf.readUnsignedByte(); + itemIndex = buf.readUnsignedByte(); + if (itemType == MAIN_NAV_DATA && (itemIndex == 0 || itemIndex == 1)) { + + position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + position.setLongitude(buf.readIntLE() / 10000000.0); + position.setLatitude(buf.readIntLE() / 10000000.0); + + short flags = buf.readUnsignedByte(); + position.setValid(BitUtil.check(flags, 7)); + if (BitUtil.check(flags, 1)) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } + + position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 20); + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShortLE()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); + position.setCourse(buf.readUnsignedShortLE()); + + position.set(Position.KEY_ODOMETER, buf.readUnsignedShortLE()); + position.setAltitude(buf.readShortLE()); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_PDOP, buf.readUnsignedByte()); + } + + itemType = buf.readUnsignedByte(); + itemIndex = buf.readUnsignedByte(); + if (itemType == ADDITIONAL_NAV_DATA && itemIndex == 0) { + + position.set(Position.KEY_BATTERY_LEVEL, Math.max((buf.readUnsignedShortLE() - 3600) / 6, 100)); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE()); + position.set(Position.PREFIX_ADC + 3, buf.readUnsignedShortLE()); + position.set(Position.PREFIX_ADC + 4, buf.readUnsignedShortLE()); + + buf.readUnsignedByte(); // inputs + buf.readUnsignedByte(); // outputs + buf.readUnsignedShortLE(); // in1 count + buf.readUnsignedShortLE(); // in2 count + buf.readUnsignedShortLE(); // in3 count + buf.readUnsignedShortLE(); // in4 count + buf.readUnsignedIntLE(); // track length + + position.set(Position.KEY_ANTENNA, buf.readUnsignedByte()); + position.set(Position.KEY_GPS, buf.readUnsignedByte()); + position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedByte() * 200); + } + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + + buf.skipBytes(2); // signature + buf.readUnsignedShortLE(); // length + buf.readUnsignedShortLE(); // connection flags + buf.readUnsignedShortLE(); // checksum + buf.readUnsignedByte(); // type + buf.readUnsignedIntLE(); // address + buf.readUnsignedShortLE(); // identification + + int serviceId = buf.readUnsignedShortLE(); + int serviceType = buf.readUnsignedShortLE(); + buf.readUnsignedShortLE(); // request flags + long requestId = buf.readUnsignedIntLE(); + + if (deviceSession == null && serviceId == NPH_SRV_GENERIC_CONTROLS && serviceType == NPH_SGC_CONN_REQUEST) { + + buf.readUnsignedShortLE(); // version major + buf.readUnsignedShortLE(); // version minor + buf.readUnsignedShortLE(); // connection flags + + int deviceId = buf.readUnsignedShortLE(); + Position position = new Position(getProtocolName()); + deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(deviceId)); + position.setDeviceId(deviceSession.getDeviceId()); + + if (channel != null) { + sendResponse(channel, serviceId, requestId); + } + + position.set(Position.KEY_RESULT, String.valueOf(NPH_SGC_RESULT)); + position.setTime(new Date()); + getLastLocation(position, new Date()); + position.setValid(false); + + return position; + + } + + if (serviceId == NPH_SRV_NAVDATA) { + + deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + if (channel != null) { + sendResponse(channel, serviceId, requestId); + } + + decodeData(buf, position); + + return position; + } + + return null; + } + +} diff --git a/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java b/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java new file mode 100644 index 000000000..7aac8658a --- /dev/null +++ b/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java @@ -0,0 +1,42 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.BaseProtocolEncoder; +import org.traccar.Protocol; +import org.traccar.model.Command; + +public class NdtpV6ProtocolEncoder extends BaseProtocolEncoder { + + public NdtpV6ProtocolEncoder(Protocol protocol) { + super(protocol); + } + + @Override + protected Object encodeCommand(Command command) { + switch (command.getType()) { + case Command.TYPE_IDENTIFICATION: + return "BB+IDNT"; + case Command.TYPE_REBOOT_DEVICE: + return "BB+RESET"; + case Command.TYPE_POSITION_SINGLE: + return "BB+RRCD"; + default: + return null; + } + } + +} -- cgit v1.2.3 From 5612d29b74a1c5ded13955565cf1b48f2307813c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 18 Sep 2022 11:31:41 -0700 Subject: Refactor G1RUS protocol --- .../org/traccar/protocol/G1rusFrameDecoder.java | 49 +++ .../java/org/traccar/protocol/G1rusProtocol.java | 18 +- .../org/traccar/protocol/G1rusProtocolDecoder.java | 412 +++++---------------- 3 files changed, 165 insertions(+), 314 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/G1rusFrameDecoder.java diff --git a/src/main/java/org/traccar/protocol/G1rusFrameDecoder.java b/src/main/java/org/traccar/protocol/G1rusFrameDecoder.java new file mode 100644 index 000000000..8c67207ad --- /dev/null +++ b/src/main/java/org/traccar/protocol/G1rusFrameDecoder.java @@ -0,0 +1,49 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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 io.netty.channel.ChannelHandlerContext; +import org.traccar.BaseFrameDecoder; + +public class G1rusFrameDecoder extends BaseFrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { + + ByteBuf result = Unpooled.buffer(); + + while (buf.isReadable()) { + int b = buf.readUnsignedByte(); + if (b == 0x1B) { + int ext = buf.readUnsignedByte(); + if (ext == 0x00) { + result.writeByte(0x1B); + } else { + result.writeByte(0xF8); + } + } else { + result.writeByte(b); + } + } + + return result; + } + +} diff --git a/src/main/java/org/traccar/protocol/G1rusProtocol.java b/src/main/java/org/traccar/protocol/G1rusProtocol.java index 0d77a8add..f1823762d 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocol.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocol.java @@ -1,6 +1,20 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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; @@ -16,9 +30,11 @@ public class G1rusProtocol extends BaseProtocol { addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new G1rusFrameDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new G1rusProtocolDecoder(G1rusProtocol.this)); } }); } + } diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index b1b7230e1..e974e446d 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -1,20 +1,30 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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 com.google.common.primitives.Ints; -import com.google.common.primitives.Longs; -import com.google.common.primitives.Shorts; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; +import org.traccar.helper.BitUtil; import org.traccar.model.Position; -import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; import java.net.SocketAddress; -import java.text.SimpleDateFormat; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -24,352 +34,128 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); + public static final int MSG_HEARTBEAT = 0; + public static final int MSG_REGULAR = 1; + public static final int MSG_SMS_FORWARD = 2; + public static final int MSG_SERIAL = 3; + public static final int MSG_MIXED = 4; - /* Constants */ - private static final int G1RUS_HEAD_TAIL = 0xF8; - - private static final int G1RUS_TYPE_HEARTBEAT = 0; - - private static final int G1RUS_TYPE_BCD_MASK = 0b00111111; - private static final int G1RUS_TYPE_REGULAR = 1; - private static final int G1RUS_TYPE_SMS_FORWARD = 2; - private static final int G1RUS_TYPE_SERIAL_PASS_THROUGH = 3; - private static final int G1RUS_TYPE_MIXED = 4; - - private static final int G1RUS_TYPE_EVENT_MASK = 0b01000000; - private static final int G1RUS_TYPE_NON_EVENT = 0; - private static final int G1RUS_TYPE_EVENT = 1; - - private static final int G1RUS_TYPE_IMEI_MASK = 0b10000000; - private static final int G1RUS_TYPE_IMEI_LONG = 0; - private static final int G1RUS_TYPE_IMEI_SHORT = 1; - - private static final int G1RUS_DATA_SYS_MASK = 0b00000001; - private static final int G1RUS_DATA_GPS_MASK = 0b00000010; - private static final int G1RUS_DATA_GSM_MASK = 0b00000100; - private static final int G1RUS_DATA_COT_MASK = 0b00001000; - private static final int G1RUS_DATA_ADC_MASK = 0b00010000; - private static final int G1RUS_DATA_DTT_MASK = 0b00100000; - /* Reserved */ - private static final int G1RUS_DATA_ETD_MASK = 0b10000000; - - private static final int G1RUS_GPS_SIGN_MASK = 0b00000001; - private static final int G1RUS_GPS_POS_MASK = 0b00000010; - private static final int G1RUS_GPS_SPD_MASK = 0b00000100; - private static final int G1RUS_GPS_AZTH_MASK = 0b00001000; - private static final int G1RUS_GPS_ALT_MASK = 0b00010000; - private static final int G1RUS_GPS_HDOP_MASK = 0b00100000; - private static final int G1RUS_GPS_VDOP_MASK = 0b01000000; - private static final int G1RUS_GPS_STAT_MASK = 0b10000000; - - private static final int G1RUS_ADC_DATA_MASK = 0b0000111111111111; + private String readString(ByteBuf buf) { + int length = buf.readUnsignedByte() & 0xF; + return buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); + } - private static final int G1RUS_ESCAPE_CHAR = 0x1B; + private Position decodeRegular(DeviceSession deviceSession, ByteBuf buf, int type) { + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.setTime(new Date((buf.readUnsignedIntLE() + 946684800) * 1000L)); - private short readUnsignedByteUnescaped(ByteBuf buf) { - short first = buf.readUnsignedByte(); - if (first != G1RUS_ESCAPE_CHAR) { - return first; - } else { /* first == 0x1B */ - byte second = (byte) buf.readUnsignedByte(); - if (second == 0x00) { - return first; - } else { /* second == 0xE3 */ - return (short) 0xF8; - } + if (BitUtil.check(type, 6)) { + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); } - } + int dataMask = buf.readUnsignedShort(); - private void skipBytesUnescaped(ByteBuf buf, int howMany) { - for (int i = 0; i < howMany; ++i) { - readUnsignedByteUnescaped(buf); + if (BitUtil.check(dataMask, 0)) { + buf.readUnsignedByte(); // length + readString(buf); // device name + position.set(Position.KEY_VERSION_FW, readString(buf)); + position.set(Position.KEY_VERSION_HW, readString(buf)); } - } - - private void readBytesUnescaped(ByteBuf buf, byte[] to) { - for (int i = 0; i < to.length; ++i) { - to[i] = (byte) readUnsignedByteUnescaped(buf); + if (BitUtil.check(dataMask, 1)) { + buf.readUnsignedByte(); // length + int locationMask = buf.readUnsignedShort(); + if (BitUtil.check(locationMask, 0)) { + int validity = buf.readUnsignedByte(); + position.set(Position.KEY_SATELLITES, BitUtil.to(validity, 5)); + position.setValid(BitUtil.between(validity, 5, 7) == 2); + } + if (BitUtil.check(locationMask, 1)) { + position.setLatitude(buf.readInt() / 1000000.0); + position.setLongitude(buf.readInt() / 1000000.0); + } + if (BitUtil.check(locationMask, 2)) { + position.setSpeed(buf.readUnsignedShort()); + } + if (BitUtil.check(locationMask, 3)) { + position.setCourse(buf.readUnsignedShort()); + } + if (BitUtil.check(locationMask, 4)) { + position.setAltitude(buf.readShort()); + } + if (BitUtil.check(locationMask, 5)) { + position.set(Position.KEY_HDOP, buf.readUnsignedShort()); + } + if (BitUtil.check(locationMask, 6)) { + position.set(Position.KEY_VDOP, buf.readUnsignedShort()); + } } - } - private void readBytesUnescaped(ByteBuf buf, byte[] to, int dstIndex, int length) { - for (int i = dstIndex; i < length; ++i) { - to[i] = (byte) readUnsignedByteUnescaped(buf); + if (BitUtil.check(dataMask, 2)) { + buf.skipBytes(buf.readUnsignedByte()); } - } - - - private int readUnsignedShortUnescaped(ByteBuf buf) { - byte[] shortBuf = new byte[2]; - readBytesUnescaped(buf, shortBuf); - return Shorts.fromByteArray(shortBuf); - } - - private int readIntUnescaped(ByteBuf buf) { - byte[] intBuf = new byte[4]; - readBytesUnescaped(buf, intBuf); - return Ints.fromByteArray(intBuf); - } - - - private void decodeSYSSub(ByteBuf buf) { - LOGGER.debug(""); - - skipBytesUnescaped(buf, 1); /* Total length */ - - /* NOTE: assuming order: - * Device name -> Firmware version -> Hardware version. - * TODO: actually check it. - */ - - /* Device name */ - short devNameLen = readUnsignedByteUnescaped(buf); - byte[] devName = new byte[devNameLen & 0xF]; - readBytesUnescaped(buf, devName); - String devNameString = new String(devName); - LOGGER.debug("Device name: " + devNameString); - - /* Firmware version */ - short firmwareLen = readUnsignedByteUnescaped(buf); - byte[] firmware = new byte[firmwareLen & 0xF]; - readBytesUnescaped(buf, firmware); - String firmwareString = new String(firmware); - LOGGER.debug("Firmware version: " + firmwareString); - - /* Hardware version */ - short hardwareLen = readUnsignedByteUnescaped(buf); - byte[] hardware = new byte[hardwareLen & 0xF]; - readBytesUnescaped(buf, hardware); - String hardwareString = new String(hardware); - LOGGER.debug("Hardware version: " + hardwareString); - - LOGGER.debug(""); - } - - - private void decodeGPSSub(ByteBuf buf, Position position) { - LOGGER.debug(""); - - skipBytesUnescaped(buf, 1); /* Total length */ - - int subMask = readUnsignedShortUnescaped(buf); - if ((subMask & G1RUS_GPS_SIGN_MASK) == G1RUS_GPS_SIGN_MASK) { - short signValid = readUnsignedByteUnescaped(buf); - LOGGER.debug("Fix sign: " + ((signValid & 0b1100000) >> 5)); - LOGGER.debug("Satellite number: " + (signValid & 0b0011111)); - position.setValid(((signValid & 0b1100000) >> 5) == 2); - position.set(Position.KEY_SATELLITES, signValid & 0b0011111); - } - if ((subMask & G1RUS_GPS_POS_MASK) == G1RUS_GPS_POS_MASK) { - byte[] posBuf = new byte[4]; - readBytesUnescaped(buf, posBuf); - position.setLatitude((float) Ints.fromByteArray(posBuf) / 1000000); - LOGGER.debug("Latitude: " + position.getLatitude()); - - readBytesUnescaped(buf, posBuf); - position.setLongitude((float) Ints.fromByteArray(posBuf) / 1000000); - LOGGER.debug("Longitude: " + position.getLongitude()); - } - if ((subMask & G1RUS_GPS_SPD_MASK) == G1RUS_GPS_SPD_MASK) { - position.setSpeed(readUnsignedShortUnescaped(buf)); - LOGGER.debug("Speed: " + position.getSpeed()); + if (BitUtil.check(dataMask, 3)) { + buf.skipBytes(buf.readUnsignedByte()); } - if ((subMask & G1RUS_GPS_AZTH_MASK) == G1RUS_GPS_AZTH_MASK) { - position.setCourse(readUnsignedShortUnescaped(buf)); - LOGGER.debug("Course: " + position.getCourse()); - } - if ((subMask & G1RUS_GPS_ALT_MASK) == G1RUS_GPS_ALT_MASK) { - position.setAltitude(readUnsignedShortUnescaped(buf)); - LOGGER.debug("Altitude: " + position.getAltitude()); - } - if ((subMask & G1RUS_GPS_HDOP_MASK) == G1RUS_GPS_HDOP_MASK) { - position.set(Position.KEY_HDOP, readUnsignedShortUnescaped(buf)); - LOGGER.debug("HDOP: " + position.getAttributes().get(Position.KEY_HDOP)); - } - if ((subMask & G1RUS_GPS_VDOP_MASK) == G1RUS_GPS_VDOP_MASK) { - position.set(Position.KEY_VDOP, readUnsignedShortUnescaped(buf)); - LOGGER.debug("VDOP: " + position.getAttributes().get(Position.KEY_VDOP)); - } - - LOGGER.debug(""); - } - - - private int getADValue(int rawValue) { - final int AD_MIN = -10; - final int AD_MAX = 100; - - return rawValue * (AD_MAX - AD_MIN) / 4096 + AD_MIN; - } - - - private void decodeADCSub(ByteBuf buf, Position position) { - LOGGER.debug(""); - - skipBytesUnescaped(buf, 1); - - /* NOTE: assuming order: - * External battery voltage -> Backup battery voltage -> Device temperature voltage. - * TODO: actually check this. - */ - - int externalVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.debug("External voltage: " + getADValue(externalVoltage) + "V [" + externalVoltage + "]"); - - int backupVoltage = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.debug("Backup voltage: " + getADValue(backupVoltage) + "V [" + backupVoltage + "]"); - position.set(Position.KEY_BATTERY, getADValue(backupVoltage)); - - int temperature = readUnsignedShortUnescaped(buf) & G1RUS_ADC_DATA_MASK; - LOGGER.debug("Device temperature: " + getADValue(temperature) + "°C [" + temperature + "]"); - position.set(Position.KEY_DEVICE_TEMP, getADValue(temperature)); - LOGGER.debug(""); - } - - - private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf, long imei, short packetType) { - int timestamp_ = readIntUnescaped(buf); - long timestamp = (946684800 + timestamp_) * 1000L; /* Convert received time to proper UNIX timestamp */ - LOGGER.debug("Date and time: " + new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date(timestamp))); - - if ((packetType & G1RUS_TYPE_EVENT_MASK) != G1RUS_TYPE_NON_EVENT) { - skipBytesUnescaped(buf, 1); /* Event ID */ + if (BitUtil.check(dataMask, 4)) { + buf.readUnsignedByte(); // length + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 110 / 4096 - 10); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 110 / 4096 - 10); + position.set(Position.KEY_DEVICE_TEMP, buf.readUnsignedShort() * 110 / 4096 - 10); } - DeviceSession deviceSession = null; - Position position = null; - - int dataUploadingMask = readUnsignedShortUnescaped(buf); - if ((dataUploadingMask & G1RUS_DATA_SYS_MASK) == G1RUS_DATA_SYS_MASK) { - decodeSYSSub(buf); + if (BitUtil.check(dataMask, 5)) { + buf.skipBytes(buf.readUnsignedByte()); } - if ((dataUploadingMask & G1RUS_DATA_GPS_MASK) == G1RUS_DATA_GPS_MASK) { - deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(imei)); - if (deviceSession == null) { - return null; - } - position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(new Date(timestamp)); - decodeGPSSub(buf, position); - } - if ((dataUploadingMask & G1RUS_DATA_GSM_MASK) == G1RUS_DATA_GSM_MASK) { - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); - } - if ((dataUploadingMask & G1RUS_DATA_COT_MASK) == G1RUS_DATA_COT_MASK) { - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); - } - if ((dataUploadingMask & G1RUS_DATA_ADC_MASK) == G1RUS_DATA_ADC_MASK) { - if (deviceSession == null) { - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); - } else { - decodeADCSub(buf, position); - } - } - if ((dataUploadingMask & G1RUS_DATA_DTT_MASK) == G1RUS_DATA_DTT_MASK) { - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); - } - if ((dataUploadingMask & G1RUS_DATA_ETD_MASK) == G1RUS_DATA_ETD_MASK) { - skipBytesUnescaped(buf, readUnsignedByteUnescaped(buf)); + if (BitUtil.check(dataMask, 7)) { + buf.skipBytes(buf.readUnsignedByte()); } return position; } - - private Object decodeSMSForward(ByteBuf buf) { - return null; - } - - - private Object decodeSerialPassThrough(ByteBuf buf) { - return null; - } - - - private void printPacketType(short packetType) { - LOGGER.debug("Packet type: " + (packetType == G1RUS_TYPE_HEARTBEAT ? "HEARTBEAT" : - "[" + ((packetType & G1RUS_TYPE_IMEI_MASK) == G1RUS_TYPE_IMEI_LONG ? "IMEI_LONG" : "IMEI_SHORT") + "]" + - "[" + ((packetType & G1RUS_TYPE_EVENT_MASK) == G1RUS_TYPE_NON_EVENT ? "NON-EVENT" : "EVENT") + "]" + - "[" + ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR ? "REGULAR" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD ? "SMS FORWARD" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH ? "PASS THROUGH" : (packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED ? "MIXED PACKED" : "RESERVED/INVALID") + "]")); - } - - @Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + ByteBuf buf = (ByteBuf) msg; - if (buf.readUnsignedByte() != G1RUS_HEAD_TAIL) { + int type = buf.readUnsignedByte(); + String imei = String.valueOf(buf.readLong()); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + if (deviceSession == null) { return null; } - LOGGER.debug("Protocol version: " + readUnsignedByteUnescaped(buf)); - - short packetType = readUnsignedByteUnescaped(buf); - printPacketType(packetType); - - byte[] imei = new byte[8]; - readBytesUnescaped(buf, imei, 0, 7); - long imeiLong = Longs.fromByteArray(imei); - LOGGER.debug("IMEI: " + imeiLong); + if (BitUtil.to(type, 6) == MSG_REGULAR) { - List positions = null; + return decodeRegular(deviceSession, buf, type); - if (packetType == G1RUS_TYPE_HEARTBEAT) { - return null; - } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { - positions = new LinkedList<>(); - Position position = decodeRegular(channel, remoteAddress, buf, imeiLong, packetType); - if (position != null) { - positions.add(position); - } - } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { - return decodeSMSForward(buf); - } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH) { - return decodeSerialPassThrough(buf); - } else if ((packetType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_MIXED) { - positions = new LinkedList<>(); + } else if (BitUtil.to(type, 6) == MSG_MIXED) { + List positions = new LinkedList<>(); while (buf.readableBytes() > 5) { - int subPacketLength = readUnsignedShortUnescaped(buf); - short subPacketType = readUnsignedByteUnescaped(buf); - printPacketType(subPacketType); - - if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_REGULAR) { - Position position = decodeRegular(channel, remoteAddress, buf, imeiLong, subPacketType); - if (position != null) { - positions.add(position); - } + int length = buf.readUnsignedShort(); + int subtype = buf.readUnsignedByte(); + if (BitUtil.to(subtype, 6) == MSG_REGULAR) { + positions.add(decodeRegular(deviceSession, buf, subtype)); } else { - skipBytesUnescaped(buf, subPacketLength - 1); + buf.skipBytes(length); } - /* else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SMS_FORWARD) { - skipBytesUnescaped(buf, subPacketLength - 1); - *//*decodeSMSForward(buf);*//* - } else if ((subPacketType & G1RUS_TYPE_BCD_MASK) == G1RUS_TYPE_SERIAL_PASS_THROUGH) { - skipBytesUnescaped(buf, subPacketLength - 1); - *//*decodeSerialPassThrough(buf);*//* - }*/ } - } else { - LOGGER.error("Unknown packet type!"); - } + return positions.isEmpty() ? null : positions; - skipBytesUnescaped(buf, 2); /* CRC */ /* TODO: actually check it */ - short tail = buf.readUnsignedByte(); - if (tail == G1RUS_HEAD_TAIL) { - LOGGER.debug("Tail: OK"); - } else { - LOGGER.error("Tail: FAIL!"); } - return positions; + buf.skipBytes(2); + buf.readUnsignedByte(); // tail + + return null; + } + } -- cgit v1.2.3 From 18513d7949a2be933541c45728a1d466be2b50a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 19 Sep 2022 17:23:36 -0700 Subject: Decode TR08X tampering alarm --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 1 + src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 7eeee5efb..a93c11cbc 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -410,6 +410,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_LOW_BATTERY; case 0x11: return Position.ALARM_POWER_OFF; + case 0x0C: case 0x13: case 0x25: return Position.ALARM_TAMPERING; diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 1570dcf32..ebda38823 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "78782526160913063918c002780fab0c44750f00040008027f14084c0038420600030c020007398e0d0a"), + Position.KEY_ALARM, Position.ALARM_TAMPERING); + verifyAttribute(decoder, binary( "7979000d940516090908081c030defbd2d0d0a"), Position.KEY_DOOR, true); -- cgit v1.2.3 From 561647947118a86256dbb584f6da450334462739 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 19 Sep 2022 19:07:26 -0700 Subject: Refactor overspeed handling --- src/main/java/org/traccar/config/Keys.java | 14 --- .../traccar/handler/events/MotionEventHandler.java | 15 --- .../handler/events/OverspeedEventHandler.java | 91 ++++++----------- .../org/traccar/session/ConnectionManager.java | 34 +------ src/main/java/org/traccar/session/DeviceState.java | 18 ++-- .../handler/events/MotionEventHandlerTest.java | 21 ---- .../handler/events/OverspeedEventHandlerTest.java | 108 ++++++--------------- 7 files changed, 70 insertions(+), 231 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index e6c3656da..ea394d914 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -326,13 +326,6 @@ public final class Keys { List.of(KeyType.SERVER, KeyType.DEVICE), 0.0); - /** - * If true, the event is generated once at the beginning of overspeeding period. - */ - public static final ConfigKey EVENT_OVERSPEED_NOT_REPEAT = new BooleanConfigKey( - "event.overspeed.notRepeat", - List.of(KeyType.CONFIG)); - /** * Minimal over speed duration to trigger the event. Value in seconds. */ @@ -598,13 +591,6 @@ public final class Keys { List.of(KeyType.CONFIG), 600L); - /** - * Force additional state check when device status changes to 'offline' or 'unknown'. Default false. - */ - public static final ConfigKey STATUS_UPDATE_DEVICE_STATE = new BooleanConfigKey( - "status.updateDeviceState", - List.of(KeyType.CONFIG)); - /** * List of protocol names to ignore offline status. Can be useful to not trigger status change when devices are * configured to disconnect after reporting a batch of data. diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 1be1896ef..7ef9ec21d 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -54,21 +54,6 @@ public class MotionEventHandler extends BaseEventHandler { return Collections.singletonMap(event, position); } - public Map updateMotionState(DeviceState deviceState) { - Map result = null; - if (deviceState.getMotionState() != null && deviceState.getMotionPosition() != null) { - boolean newMotion = !deviceState.getMotionState(); - Position motionPosition = deviceState.getMotionPosition(); - long currentTime = System.currentTimeMillis(); - long motionTime = motionPosition.getFixTime().getTime() - + (newMotion ? tripsConfig.getMinimalTripDuration() : tripsConfig.getMinimalParkingDuration()); - if (motionTime <= currentTime) { - result = newEvent(deviceState, newMotion); - } - } - return result; - } - public Map updateMotionState(DeviceState deviceState, Position position) { return updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 7f3675308..cfba56a38 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -42,7 +42,6 @@ public class OverspeedEventHandler extends BaseEventHandler { private final ConnectionManager connectionManager; private final CacheManager cacheManager; - private final boolean notRepeat; private final long minimalDuration; private final boolean preferLowest; @@ -50,66 +49,46 @@ public class OverspeedEventHandler extends BaseEventHandler { public OverspeedEventHandler(Config config, ConnectionManager connectionManager, CacheManager cacheManager) { this.connectionManager = connectionManager; this.cacheManager = cacheManager; - notRepeat = config.getBoolean(Keys.EVENT_OVERSPEED_NOT_REPEAT); minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000; preferLowest = config.getBoolean(Keys.EVENT_OVERSPEED_PREFER_LOWEST); } - private Map newEvent(DeviceState deviceState, double speedLimit) { - Position position = deviceState.getOverspeedPosition(); - Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); - event.set(ATTRIBUTE_SPEED, deviceState.getOverspeedPosition().getSpeed()); - event.set(Position.KEY_SPEED_LIMIT, speedLimit); - event.setGeofenceId(deviceState.getOverspeedGeofenceId()); - deviceState.setOverspeedState(notRepeat); - deviceState.setOverspeedPosition(null); - deviceState.setOverspeedGeofenceId(0); - return Collections.singletonMap(event, position); - } - - public Map updateOverspeedState(DeviceState deviceState, double speedLimit) { - Map result = null; - if (deviceState.getOverspeedState() != null && !deviceState.getOverspeedState() - && deviceState.getOverspeedPosition() != null && speedLimit != 0) { - long currentTime = System.currentTimeMillis(); - Position overspeedPosition = deviceState.getOverspeedPosition(); - long overspeedTime = overspeedPosition.getFixTime().getTime(); - if (overspeedTime + minimalDuration <= currentTime) { - result = newEvent(deviceState, speedLimit); - } - } - return result; - } - public Map updateOverspeedState( DeviceState deviceState, Position position, double speedLimit, long geofenceId) { - Map result = null; - Boolean oldOverspeed = deviceState.getOverspeedState(); + boolean oldState = deviceState.getOverspeedState(); + if (oldState) { + boolean newState = position.getSpeed() > speedLimit; + if (newState) { + if (deviceState.getOverspeedTime() != null) { + long oldTime = deviceState.getOverspeedTime().getTime(); + long newTime = position.getFixTime().getTime(); + if (newTime - oldTime > minimalDuration) { - long currentTime = position.getFixTime().getTime(); - boolean newOverspeed = position.getSpeed() > speedLimit; - if (newOverspeed && !oldOverspeed) { - if (deviceState.getOverspeedPosition() == null) { - deviceState.setOverspeedPosition(position); - deviceState.setOverspeedGeofenceId(geofenceId); - } - } else if (oldOverspeed && !newOverspeed) { - deviceState.setOverspeedState(false); - deviceState.setOverspeedPosition(null); - deviceState.setOverspeedGeofenceId(0); - } else { - deviceState.setOverspeedPosition(null); - deviceState.setOverspeedGeofenceId(0); - } - Position overspeedPosition = deviceState.getOverspeedPosition(); - if (overspeedPosition != null) { - long overspeedTime = overspeedPosition.getFixTime().getTime(); - if (newOverspeed && overspeedTime + minimalDuration <= currentTime) { - result = newEvent(deviceState, speedLimit); + Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); + event.set(ATTRIBUTE_SPEED, position.getSpeed()); + event.set(Position.KEY_SPEED_LIMIT, speedLimit); + event.setGeofenceId(deviceState.getOverspeedGeofenceId()); + + deviceState.setOverspeedTime(null); + deviceState.setOverspeedGeofenceId(0); + + return Collections.singletonMap(event, position); + + } + } + } else { + deviceState.setOverspeedState(false); + deviceState.setOverspeedTime(null); + deviceState.setOverspeedGeofenceId(0); } + } else if (position != null && position.getSpeed() > speedLimit) { + deviceState.setOverspeedState(true); + deviceState.setOverspeedTime(position.getFixTime()); + deviceState.setOverspeedGeofenceId(geofenceId); } - return result; + + return null; } @Override @@ -156,16 +135,8 @@ public class OverspeedEventHandler extends BaseEventHandler { return null; } - Map result = null; DeviceState deviceState = connectionManager.getDeviceState(deviceId); - - if (deviceState.getOverspeedState() == null) { - deviceState.setOverspeedState(position.getSpeed() > speedLimit); - deviceState.setOverspeedGeofenceId(position.getSpeed() > speedLimit ? overspeedGeofenceId : 0); - } else { - result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); - } - + Map result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); connectionManager.setDeviceState(deviceId, deviceState); return result; } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 262a302af..c826b99db 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -15,7 +15,6 @@ */ package org.traccar.session; -import com.google.inject.Injector; import io.netty.channel.Channel; import io.netty.util.Timeout; import io.netty.util.Timer; @@ -28,9 +27,6 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.DeviceLookupService; import org.traccar.database.NotificationManager; -import org.traccar.handler.events.MotionEventHandler; -import org.traccar.handler.events.OverspeedEventHandler; -import org.traccar.helper.model.AttributeUtil; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Event; @@ -66,14 +62,12 @@ public class ConnectionManager implements BroadcastInterface { private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class); private final long deviceTimeout; - private final boolean updateDeviceState; private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); private final Map deviceStates = new ConcurrentHashMap<>(); - private final Injector injector; private final Config config; private final CacheManager cacheManager; private final Storage storage; @@ -90,10 +84,9 @@ public class ConnectionManager implements BroadcastInterface { @Inject public ConnectionManager( - Injector injector, Config config, CacheManager cacheManager, Storage storage, + Config config, CacheManager cacheManager, Storage storage, NotificationManager notificationManager, Timer timer, BroadcastService broadcastService, DeviceLookupService deviceLookupService) { - this.injector = injector; this.config = config; this.cacheManager = cacheManager; this.storage = storage; @@ -102,7 +95,6 @@ public class ConnectionManager implements BroadcastInterface { this.broadcastService = broadcastService; this.deviceLookupService = deviceLookupService; deviceTimeout = config.getLong(Keys.STATUS_TIMEOUT); - updateDeviceState = config.getBoolean(Keys.STATUS_UPDATE_DEVICE_STATE); broadcastService.registerListener(this); } @@ -246,15 +238,9 @@ public class ConnectionManager implements BroadcastInterface { break; case Device.STATUS_UNKNOWN: eventType = Event.TYPE_DEVICE_UNKNOWN; - if (updateDeviceState) { - events.putAll(updateDeviceState(deviceId)); - } break; default: eventType = Event.TYPE_DEVICE_OFFLINE; - if (updateDeviceState) { - events.putAll(updateDeviceState(deviceId)); - } break; } events.put(new Event(eventType, deviceId), null); @@ -297,24 +283,6 @@ public class ConnectionManager implements BroadcastInterface { deviceStates.put(deviceId, deviceState); } - public Map updateDeviceState(long deviceId) { - DeviceState deviceState = getDeviceState(deviceId); - Map result = new HashMap<>(); - - Map event = injector.getInstance(MotionEventHandler.class).updateMotionState(deviceState); - if (event != null) { - result.putAll(event); - } - - double speedLimit = AttributeUtil.lookup(cacheManager, Keys.EVENT_OVERSPEED_LIMIT, deviceId); - event = injector.getInstance(OverspeedEventHandler.class).updateOverspeedState(deviceState, speedLimit); - if (event != null) { - result.putAll(event); - } - - return result; - } - public synchronized void sendKeepalive() { for (Set userListeners : listeners.values()) { for (UpdateListener listener : userListeners) { diff --git a/src/main/java/org/traccar/session/DeviceState.java b/src/main/java/org/traccar/session/DeviceState.java index b7248688a..f67b906c4 100644 --- a/src/main/java/org/traccar/session/DeviceState.java +++ b/src/main/java/org/traccar/session/DeviceState.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,8 @@ package org.traccar.session; import org.traccar.model.Position; +import java.util.Date; + public class DeviceState { private Boolean motionState; @@ -40,24 +42,24 @@ public class DeviceState { return motionPosition; } - private Boolean overspeedState; + private boolean overspeedState; public void setOverspeedState(boolean overspeedState) { this.overspeedState = overspeedState; } - public Boolean getOverspeedState() { + public boolean getOverspeedState() { return overspeedState; } - private Position overspeedPosition; + private Date overspeedTime; - public void setOverspeedPosition(Position overspeedPosition) { - this.overspeedPosition = overspeedPosition; + public Date getOverspeedTime() { + return overspeedTime; } - public Position getOverspeedPosition() { - return overspeedPosition; + public void setOverspeedTime(Date overspeedTime) { + this.overspeedTime = overspeedTime; } private long overspeedGeofenceId; diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 780d1b833..1f6212eec 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -69,27 +69,6 @@ public class MotionEventHandlerTest extends BaseTest { assertNull(deviceState.getMotionPosition()); } - @Test - public void testMotionWithStatus() throws Exception { - MotionEventHandler motionEventHandler = new MotionEventHandler( - null, null, new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false, false, 0.01)); - - Position position = new Position(); - position.setTime(new Date(System.currentTimeMillis() - 360000)); - position.set(Position.KEY_MOTION, true); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(false); - deviceState.setMotionPosition(position); - - Map events = motionEventHandler.updateMotionState(deviceState); - - assertNotNull(events); - Event event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); - assertTrue(deviceState.getMotionState()); - assertNull(deviceState.getMotionPosition()); - } - @Test public void testStopWithPositionIgnition() throws Exception { MotionEventHandler motionEventHandler = new MotionEventHandler( diff --git a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java index 46e142935..bbddbae72 100644 --- a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java @@ -11,118 +11,66 @@ import org.traccar.session.DeviceState; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; import java.util.TimeZone; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; public class OverspeedEventHandlerTest extends BaseTest { - private Date date(String time) throws ParseException { + private Position position(String time, double speed) throws ParseException { + Position position = new Position(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - return dateFormat.parse(time); + position.setTime(dateFormat.parse(time)); + position.setSpeed(speed); + return position; + } + + private void verifyState(DeviceState deviceState, boolean state, long geofenceId) { + assertEquals(state, deviceState.getOverspeedState()); + assertEquals(geofenceId, deviceState.getOverspeedGeofenceId()); } - private void testOverspeedWithPosition(boolean notRepeat, long geofenceId) throws ParseException { + private void testOverspeedWithPosition(long geofenceId) throws ParseException { Config config = new Config(); - config.setString(Keys.EVENT_OVERSPEED_NOT_REPEAT, String.valueOf(notRepeat)); config.setString(Keys.EVENT_OVERSPEED_MINIMAL_DURATION, String.valueOf(15)); config.setString(Keys.EVENT_OVERSPEED_PREFER_LOWEST, String.valueOf(false)); OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(config, null, null); - Position position = new Position(); - position.setTime(date("2017-01-01 00:00:00")); - position.setSpeed(50); DeviceState deviceState = new DeviceState(); - deviceState.setOverspeedState(false); - - Map events = overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId); - assertNull(events); - assertFalse(deviceState.getOverspeedState()); - assertEquals(position, deviceState.getOverspeedPosition()); - assertEquals(geofenceId, deviceState.getOverspeedGeofenceId()); - Position nextPosition = new Position(); - nextPosition.setTime(date("2017-01-01 00:00:10")); - nextPosition.setSpeed(55); + Position position = position("2017-01-01 00:00:00", 50); + assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); + verifyState(deviceState, true, geofenceId); - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); - assertNull(events); + position = position("2017-01-01 00:00:10", 55); + assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); - nextPosition.setTime(date("2017-01-01 00:00:20")); - - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); + position = position("2017-01-01 00:00:20", 55); + var events = overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId); assertNotNull(events); Event event = events.keySet().iterator().next(); assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); - assertEquals(50, event.getDouble("speed"), 0.1); + assertEquals(55, event.getDouble("speed"), 0.1); assertEquals(40, event.getDouble("speedLimit"), 0.1); assertEquals(geofenceId, event.getGeofenceId()); + verifyState(deviceState, true, 0); - assertEquals(notRepeat, deviceState.getOverspeedState()); - assertNull(deviceState.getOverspeedPosition()); - assertEquals(0, deviceState.getOverspeedGeofenceId()); - - nextPosition.setTime(date("2017-01-01 00:00:30")); - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); - assertNull(events); - assertEquals(notRepeat, deviceState.getOverspeedState()); - - if (notRepeat) { - assertNull(deviceState.getOverspeedPosition()); - assertEquals(0, deviceState.getOverspeedGeofenceId()); - } else { - assertNotNull(deviceState.getOverspeedPosition()); - assertEquals(geofenceId, deviceState.getOverspeedGeofenceId()); - } - - nextPosition.setTime(date("2017-01-01 00:00:40")); - nextPosition.setSpeed(30); - - events = overspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, geofenceId); - assertNull(events); - assertFalse(deviceState.getOverspeedState()); - assertNull(deviceState.getOverspeedPosition()); - assertEquals(0, deviceState.getOverspeedGeofenceId()); - } - - private void testOverspeedWithStatus(boolean notRepeat) { - Config config = new Config(); - config.setString(Keys.EVENT_OVERSPEED_NOT_REPEAT, String.valueOf(notRepeat)); - config.setString(Keys.EVENT_OVERSPEED_MINIMAL_DURATION, String.valueOf(15)); - config.setString(Keys.EVENT_OVERSPEED_PREFER_LOWEST, String.valueOf(false)); - OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(config, null, null); + position = position("2017-01-01 00:00:30", 55); + assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); + verifyState(deviceState, true, 0); - Position position = new Position(); - position.setTime(new Date(System.currentTimeMillis() - 30000)); - position.setSpeed(50); - DeviceState deviceState = new DeviceState(); - deviceState.setOverspeedState(false); - deviceState.setOverspeedPosition(position); - - Map events = overspeedEventHandler.updateOverspeedState(deviceState, 40); - - assertNotNull(events); - Event event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); - assertEquals(notRepeat, deviceState.getOverspeedState()); + position = position("2017-01-01 00:00:30", 30); + assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); + verifyState(deviceState, false, 0); } @Test public void testOverspeedEventHandler() throws Exception { - testOverspeedWithPosition(false, 0); - testOverspeedWithPosition(true, 0); - - testOverspeedWithPosition(false, 1); - testOverspeedWithPosition(true, 1); - - testOverspeedWithStatus(false); - testOverspeedWithStatus(true); + testOverspeedWithPosition(0); + testOverspeedWithPosition(1); } } -- cgit v1.2.3 From 388799edf2adc9c3070a83e72f074e523629574f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 21 Sep 2022 17:53:50 -0700 Subject: Refactor motion handling --- .../traccar/handler/events/MotionEventHandler.java | 88 ++++++++--------- .../handler/events/OverspeedEventHandler.java | 2 +- .../org/traccar/reports/common/ReportUtils.java | 53 +++++----- src/main/java/org/traccar/session/DeviceState.java | 26 +++-- .../handler/events/MotionEventHandlerTest.java | 108 +++++++++------------ .../java/org/traccar/reports/ReportUtilsTest.java | 24 ++--- 6 files changed, 143 insertions(+), 158 deletions(-) diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 7ef9ec21d..234899785 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -45,54 +45,52 @@ public class MotionEventHandler extends BaseEventHandler { this.tripsConfig = tripsConfig; } - private Map newEvent(DeviceState deviceState, boolean newMotion) { - String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; - Position position = deviceState.getMotionPosition(); - Event event = new Event(eventType, position); - deviceState.setMotionState(newMotion); - deviceState.setMotionPosition(null); - return Collections.singletonMap(event, position); - } - - public Map updateMotionState(DeviceState deviceState, Position position) { - return updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - } + public Map updateMotionState(DeviceState deviceState, Position position, boolean newState) { - public Map updateMotionState(DeviceState deviceState, Position position, boolean newMotion) { - Map result = null; - Boolean oldMotion = deviceState.getMotionState(); + boolean oldState = deviceState.getMotionState(); + if (oldState == newState) { + if (deviceState.getMotionTime() != null) { + long oldTime = deviceState.getMotionTime().getTime(); + long newTime = position.getFixTime().getTime(); - long currentTime = position.getFixTime().getTime(); - if (newMotion != oldMotion) { - if (deviceState.getMotionPosition() == null) { - deviceState.setMotionPosition(position); - } - } else { - deviceState.setMotionPosition(null); - } + double distance = position.getDouble(Position.KEY_TOTAL_DISTANCE) - deviceState.getMotionDistance(); + Boolean ignition = null; + if (tripsConfig.getUseIgnition() && position.hasAttribute(Position.KEY_IGNITION)) { + ignition = position.getBoolean(Position.KEY_IGNITION); + } - Position motionPosition = deviceState.getMotionPosition(); - if (motionPosition != null) { - long motionTime = motionPosition.getFixTime().getTime(); - double distance = PositionUtil.calculateDistance(motionPosition, position, false); - Boolean ignition = null; - if (tripsConfig.getUseIgnition() - && position.hasAttribute(Position.KEY_IGNITION)) { - ignition = position.getBoolean(Position.KEY_IGNITION); - } - if (newMotion) { - if (motionTime + tripsConfig.getMinimalTripDuration() <= currentTime - || distance >= tripsConfig.getMinimalTripDistance()) { - result = newEvent(deviceState, newMotion); + boolean generateEvent = false; + if (newState) { + if (newTime - oldTime >= tripsConfig.getMinimalTripDuration() + || distance >= tripsConfig.getMinimalTripDistance()) { + generateEvent = true; + } + } else { + if (newTime - oldTime >= tripsConfig.getMinimalParkingDuration() + || ignition != null && !ignition) { + generateEvent = true; + } } - } else { - if (motionTime + tripsConfig.getMinimalParkingDuration() <= currentTime - || ignition != null && !ignition) { - result = newEvent(deviceState, newMotion); + + if (generateEvent) { + + String eventType = newState ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; + Event event = new Event(eventType, position); + + deviceState.setMotionTime(null); + deviceState.setMotionDistance(0); + + return Collections.singletonMap(event, position); + } } + } else { + deviceState.setMotionState(newState); + deviceState.setMotionTime(position.getFixTime()); + deviceState.setMotionDistance(position.getDouble(Position.KEY_TOTAL_DISTANCE)); } - return result; + + return null; } @Override @@ -108,14 +106,8 @@ public class MotionEventHandler extends BaseEventHandler { return null; } - Map result = null; DeviceState deviceState = connectionManager.getDeviceState(deviceId); - - if (deviceState.getMotionState() == null) { - deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); - } else { - result = updateMotionState(deviceState, position); - } + var result = updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); connectionManager.setDeviceState(deviceId, deviceState); return result; } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index cfba56a38..3984299d7 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -136,7 +136,7 @@ public class OverspeedEventHandler extends BaseEventHandler { } DeviceState deviceState = connectionManager.getDeviceState(deviceId); - Map result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); + var result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); connectionManager.setDeviceState(deviceId, deviceState); return result; } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 7fff46f66..2bca00df7 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -37,7 +37,6 @@ import org.traccar.helper.model.UserUtil; import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Driver; -import org.traccar.model.Event; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.User; @@ -65,7 +64,6 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @@ -353,38 +351,39 @@ public class ReportUtils { if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); MotionEventHandler motionHandler = new MotionEventHandler(null, null, tripsConfig); + DeviceState deviceState = new DeviceState(); deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); - int startEventIndex = trips == deviceState.getMotionState() ? 0 : -1; + + boolean detected = trips == deviceState.getMotionState(); + int startEventIndex = detected ? 0 : -1; int startNoEventIndex = -1; for (int i = 0; i < positions.size(); i++) { - Map event = motionHandler.updateMotionState(deviceState, positions.get(i), - isMoving(positions, i, tripsConfig)); - if (startEventIndex == -1 - && (trips != deviceState.getMotionState() && deviceState.getMotionPosition() != null - || trips == deviceState.getMotionState() && event != null)) { - startEventIndex = i; - startNoEventIndex = -1; - } else if (trips != deviceState.getMotionState() && startEventIndex != -1 - && deviceState.getMotionPosition() == null && event == null) { - startEventIndex = -1; + boolean motion = isMoving(positions, i, tripsConfig); + if (deviceState.getMotionState() != motion) { + if (motion == trips) { + startEventIndex = detected ? startEventIndex : i; + startNoEventIndex = -1; + } else { + startNoEventIndex = i; + } } - if (startNoEventIndex == -1 - && (trips == deviceState.getMotionState() && deviceState.getMotionPosition() != null - || trips != deviceState.getMotionState() && event != null)) { - startNoEventIndex = i; - } else if (startNoEventIndex != -1 && deviceState.getMotionPosition() == null && event == null) { - startNoEventIndex = -1; - } - if (startEventIndex != -1 && startNoEventIndex != -1 && event != null - && trips != deviceState.getMotionState()) { - result.add(calculateTripOrStop( - device, positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); - startEventIndex = -1; + + if (motionHandler.updateMotionState(deviceState, positions.get(i), motion) != null) { + if (motion == trips) { + detected = true; + startNoEventIndex = -1; + } else if (startEventIndex >= 0 && startNoEventIndex >= 0) { + result.add(calculateTripOrStop( + device, positions, startEventIndex, startNoEventIndex, ignoreOdometer, reportClass)); + detected = false; + startEventIndex = -1; + startNoEventIndex = -1; + } } } - if (startEventIndex != -1 && (startNoEventIndex != -1 || !trips)) { - int endIndex = startNoEventIndex != -1 ? startNoEventIndex : positions.size() - 1; + if (startEventIndex >= 0 && startEventIndex < positions.size() - 1) { + int endIndex = startNoEventIndex >= 0 ? startNoEventIndex : positions.size() - 1; result.add(calculateTripOrStop( device, positions, startEventIndex, endIndex, ignoreOdometer, reportClass)); } diff --git a/src/main/java/org/traccar/session/DeviceState.java b/src/main/java/org/traccar/session/DeviceState.java index f67b906c4..7bf2a62ac 100644 --- a/src/main/java/org/traccar/session/DeviceState.java +++ b/src/main/java/org/traccar/session/DeviceState.java @@ -16,30 +16,38 @@ */ package org.traccar.session; -import org.traccar.model.Position; - import java.util.Date; public class DeviceState { - private Boolean motionState; + private boolean motionState; public void setMotionState(boolean motionState) { this.motionState = motionState; } - public Boolean getMotionState() { + public boolean getMotionState() { return motionState; } - private Position motionPosition; + private Date motionTime; + + public Date getMotionTime() { + return motionTime; + } + + public void setMotionTime(Date motionTime) { + this.motionTime = motionTime; + } + + private double motionDistance; - public void setMotionPosition(Position motionPosition) { - this.motionPosition = motionPosition; + public double getMotionDistance() { + return motionDistance; } - public Position getMotionPosition() { - return motionPosition; + public void setMotionDistance(double motionDistance) { + this.motionDistance = motionDistance; } private boolean overspeedState; diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 1f6212eec..0d4886429 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -10,89 +10,75 @@ import org.traccar.session.DeviceState; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; import java.util.TimeZone; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; public class MotionEventHandlerTest extends BaseTest { - private Date date(String time) throws ParseException { + private Position position(String time, boolean motion, double distance, Boolean ignition) throws ParseException { + Position position = new Position(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - return dateFormat.parse(time); + position.setTime(dateFormat.parse(time)); + position.set(Position.KEY_MOTION, motion); + position.set(Position.KEY_TOTAL_DISTANCE, distance); + position.set(Position.KEY_IGNITION, ignition); + return position; + } + + private void verifyState(DeviceState deviceState, boolean state, long distance) { + assertEquals(state, deviceState.getMotionState()); + assertEquals(distance, deviceState.getMotionDistance(), 0.1); } @Test - public void testMotionWithPosition() throws Exception { + public void testMotionWithPosition() throws ParseException { MotionEventHandler motionEventHandler = new MotionEventHandler( - null, null, new TripsConfig(500, 300 * 1000, 300 * 1000, 0, false, false, 0.01)); + null, null, new TripsConfig(500, 300000, 300000, 0, false, false, 0.01)); - Position position = new Position(); - position.setTime(date("2017-01-01 00:00:00")); - position.set(Position.KEY_MOTION, true); - position.set(Position.KEY_TOTAL_DISTANCE, 0); DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(false); - deviceState.setMotionPosition(position); - Position nextPosition = new Position(); - - nextPosition.setTime(date("2017-01-01 00:02:00")); - nextPosition.set(Position.KEY_MOTION, true); - nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); - - Map events = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNull(events); - - nextPosition.set(Position.KEY_TOTAL_DISTANCE, 600); - events = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNotNull(events); - Event event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); - assertTrue(deviceState.getMotionState()); - assertNull(deviceState.getMotionPosition()); - - deviceState.setMotionState(false); - deviceState.setMotionPosition(position); - nextPosition.setTime(date("2017-01-01 00:06:00")); - nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); - events = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNotNull(event); - event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); - assertTrue(deviceState.getMotionState()); - assertNull(deviceState.getMotionPosition()); + + Position position = position("2017-01-01 00:00:00", false, 0, null); + assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); + verifyState(deviceState, false, 0); + + position = position("2017-01-01 00:02:00", true, 100, null); + assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); + verifyState(deviceState, true, 100); + + position = position("2017-01-01 00:02:00", true, 700, null); + var events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); + assertEquals(Event.TYPE_DEVICE_MOVING, events.keySet().iterator().next().getType()); + verifyState(deviceState, true, 0); + + position = position("2017-01-01 00:03:00", false, 700, null); + assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); + verifyState(deviceState, false, 700); + + position = position("2017-01-01 00:10:00", false, 700, null); + events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); + assertEquals(Event.TYPE_DEVICE_STOPPED, events.keySet().iterator().next().getType()); + verifyState(deviceState, false, 0); } @Test - public void testStopWithPositionIgnition() throws Exception { + public void testStopWithPositionIgnition() throws ParseException { MotionEventHandler motionEventHandler = new MotionEventHandler( - null, null, new TripsConfig(500, 300 * 1000, 300 * 1000, 0, true, false, 0.01)); + null, null, new TripsConfig(500, 300000, 300000, 0, true, false, 0.01)); - Position position = new Position(); - position.setTime(date("2017-01-01 00:00:00")); - position.set(Position.KEY_MOTION, false); - position.set(Position.KEY_IGNITION, true); DeviceState deviceState = new DeviceState(); deviceState.setMotionState(true); - deviceState.setMotionPosition(position); - - Position nextPosition = new Position(); - nextPosition.setTime(date("2017-01-01 00:02:00")); - nextPosition.set(Position.KEY_MOTION, false); - nextPosition.set(Position.KEY_IGNITION, false); - - Map events = motionEventHandler.updateMotionState(deviceState, nextPosition); - assertNotNull(events); - Event event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_STOPPED, event.getType()); - assertFalse(deviceState.getMotionState()); - assertNull(deviceState.getMotionPosition()); + + Position position = position("2017-01-01 00:00:00", false, 100, true); + assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); + verifyState(deviceState, false, 100); + + position = position("2017-01-01 00:02:00", false, 100, false); + var events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); + assertEquals(Event.TYPE_DEVICE_STOPPED, events.keySet().iterator().next().getType()); + verifyState(deviceState, false, 0); } } diff --git a/src/test/java/org/traccar/reports/ReportUtilsTest.java b/src/test/java/org/traccar/reports/ReportUtilsTest.java index aecb1c4a4..4bf668064 100644 --- a/src/test/java/org/traccar/reports/ReportUtilsTest.java +++ b/src/test/java/org/traccar/reports/ReportUtilsTest.java @@ -106,7 +106,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(mock(Device.class), data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(mock(Device.class), data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -120,7 +120,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -161,7 +161,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -189,7 +189,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(3000, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -232,7 +232,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -246,7 +246,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(10, itemTrip.getMaxSpeed(), 0.01); assertEquals(7000, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); @@ -283,7 +283,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -312,7 +312,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -341,7 +341,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertFalse(result.isEmpty()); @@ -370,7 +370,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var result = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(result); assertTrue(result.isEmpty()); @@ -395,7 +395,7 @@ public class ReportUtilsTest extends BaseTest { mock(Config.class), storage, mock(PermissionsService.class), tripsConfig, mock(VelocityEngine.class), null); - Collection trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); + var trips = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, TripReportItem.class); assertNotNull(trips); assertFalse(trips.isEmpty()); @@ -409,7 +409,7 @@ public class ReportUtilsTest extends BaseTest { assertEquals(7, itemTrip.getMaxSpeed(), 0.01); assertEquals(600, itemTrip.getDistance(), 0.01); - Collection stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); + var stops = reportUtils.detectTripsAndStops(mock(Device.class) ,data, false, StopReportItem.class); assertNotNull(stops); assertFalse(stops.isEmpty()); -- cgit v1.2.3 From 09bb085ae8f5f218c10487a66816529598842f27 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 21 Sep 2022 17:55:34 -0700 Subject: Add space --- src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java b/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java index 54a8aaa14..d327930b5 100644 --- a/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java @@ -15,6 +15,7 @@ public class Xexun2FrameEncoderTest extends ProtocolTest { ByteBuf result = Unpooled.buffer(); encoder.encode(null, binary("FAAF123456FAAF123456FBBF123456FAAF"), result); verifyFrame(binary("FAAF123456FBBF01123456FBBF02123456FAAF"), result); + } } -- cgit v1.2.3 From 13b065fc4e8e1a4dc1f35312869151418fc660bd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 21 Sep 2022 21:03:04 -0700 Subject: Reformat forwarding request --- .../org/traccar/notification/EventForwarder.java | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/notification/EventForwarder.java b/src/main/java/org/traccar/notification/EventForwarder.java index 279d5e678..50f17a852 100644 --- a/src/main/java/org/traccar/notification/EventForwarder.java +++ b/src/main/java/org/traccar/notification/EventForwarder.java @@ -68,18 +68,17 @@ public class EventForwarder { } LOGGER.debug("Event forwarding initiated"); - requestBuilder.async().post( - Entity.json(preparePayload(event, position)), new InvocationCallback() { - @Override - public void completed(Object o) { - LOGGER.debug("Event forwarding succeeded"); - } + requestBuilder.async().post(Entity.json(preparePayload(event, position)), new InvocationCallback<>() { + @Override + public void completed(Object o) { + LOGGER.debug("Event forwarding succeeded"); + } - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Event forwarding failed", throwable); - } - }); + @Override + public void failed(Throwable throwable) { + LOGGER.warn("Event forwarding failed", throwable); + } + }); } protected Map preparePayload(Event event, Position position) { -- cgit v1.2.3 From abb26e80a5617424d960a0f7d0b98fcb379a5224 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 21 Sep 2022 21:47:45 -0700 Subject: Fix forwarding date format --- src/main/java/org/traccar/MainModule.java | 9 +++-- .../helper/ObjectMapperContextResolver.java | 38 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/traccar/helper/ObjectMapperContextResolver.java diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index e0617a734..94669915b 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -62,6 +62,7 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.helper.ObjectMapperContextResolver; import org.traccar.helper.SanitizerModule; import org.traccar.mail.LogMailManager; import org.traccar.mail.MailManager; @@ -81,7 +82,6 @@ import javax.annotation.Nullable; import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.ext.ContextResolver; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; @@ -110,14 +110,13 @@ public class MainModule extends AbstractModule { objectMapper.registerModule(new SanitizerModule()); } objectMapper.registerModule(new JSR353Module()); - objectMapper.setConfig(objectMapper - .getSerializationConfig().without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return objectMapper; } @Provides - public static Client provideClient(ObjectMapper objectMapper) { - return ClientBuilder.newClient().register((ContextResolver) clazz -> objectMapper); + public static Client provideClient(ObjectMapperContextResolver objectMapperContextResolver) { + return ClientBuilder.newClient().register(objectMapperContextResolver); } @Singleton diff --git a/src/main/java/org/traccar/helper/ObjectMapperContextResolver.java b/src/main/java/org/traccar/helper/ObjectMapperContextResolver.java new file mode 100644 index 000000000..b40e30d76 --- /dev/null +++ b/src/main/java/org/traccar/helper/ObjectMapperContextResolver.java @@ -0,0 +1,38 @@ +/* + * Copyright 2022 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import javax.inject.Inject; +import javax.ws.rs.ext.ContextResolver; + +// This does not work as a lambda +public class ObjectMapperContextResolver implements ContextResolver { + + private final ObjectMapper objectMapper; + + @Inject + public ObjectMapperContextResolver(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public ObjectMapper getContext(Class clazz) { + return objectMapper; + } + +} -- cgit v1.2.3 From fe3d9995cceb2f1530a7c2549ae9a4cf457cb7f0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 25 Sep 2022 10:35:20 -0700 Subject: Persist device state --- schema/changelog-5.4.xml | 22 ++++++ schema/changelog-master.xml | 1 + .../traccar/handler/events/MotionEventHandler.java | 84 +++++++-------------- .../handler/events/OverspeedEventHandler.java | 80 +++++++------------- src/main/java/org/traccar/model/Device.java | 79 +++++++++++++++++++ .../org/traccar/reports/common/ReportUtils.java | 16 ++-- .../org/traccar/session/ConnectionManager.java | 10 --- src/main/java/org/traccar/session/DeviceState.java | 83 -------------------- .../org/traccar/session/state/MotionProcessor.java | 75 ++++++++++++++++++ .../org/traccar/session/state/MotionState.java | 88 ++++++++++++++++++++++ .../traccar/session/state/OverspeedProcessor.java | 65 ++++++++++++++++ .../org/traccar/session/state/OverspeedState.java | 88 ++++++++++++++++++++++ .../handler/events/MotionEventHandlerTest.java | 66 ++++++++-------- .../handler/events/OverspeedEventHandlerTest.java | 56 ++++++-------- 14 files changed, 537 insertions(+), 276 deletions(-) create mode 100644 schema/changelog-5.4.xml delete mode 100644 src/main/java/org/traccar/session/DeviceState.java create mode 100644 src/main/java/org/traccar/session/state/MotionProcessor.java create mode 100644 src/main/java/org/traccar/session/state/MotionState.java create mode 100644 src/main/java/org/traccar/session/state/OverspeedProcessor.java create mode 100644 src/main/java/org/traccar/session/state/OverspeedState.java diff --git a/schema/changelog-5.4.xml b/schema/changelog-5.4.xml new file mode 100644 index 000000000..f3a13ef59 --- /dev/null +++ b/schema/changelog-5.4.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index cea15397d..e877c1afd 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -34,5 +34,6 @@ + diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 234899785..0777f353a 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -17,14 +17,21 @@ package org.traccar.handler.events; import io.netty.channel.ChannelHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.common.TripsConfig; -import org.traccar.session.ConnectionManager; -import org.traccar.session.DeviceState; import org.traccar.session.cache.CacheManager; +import org.traccar.session.state.MotionProcessor; +import org.traccar.session.state.MotionState; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.util.Collections; @@ -33,66 +40,20 @@ import java.util.Map; @ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { + private static final Logger LOGGER = LoggerFactory.getLogger(MotionEventHandler.class); + private final CacheManager cacheManager; - private final ConnectionManager connectionManager; + private final Storage storage; private final TripsConfig tripsConfig; @Inject public MotionEventHandler( - CacheManager cacheManager, ConnectionManager connectionManager, TripsConfig tripsConfig) { + CacheManager cacheManager, Storage storage, TripsConfig tripsConfig) { this.cacheManager = cacheManager; - this.connectionManager = connectionManager; + this.storage = storage; this.tripsConfig = tripsConfig; } - public Map updateMotionState(DeviceState deviceState, Position position, boolean newState) { - - boolean oldState = deviceState.getMotionState(); - if (oldState == newState) { - if (deviceState.getMotionTime() != null) { - long oldTime = deviceState.getMotionTime().getTime(); - long newTime = position.getFixTime().getTime(); - - double distance = position.getDouble(Position.KEY_TOTAL_DISTANCE) - deviceState.getMotionDistance(); - Boolean ignition = null; - if (tripsConfig.getUseIgnition() && position.hasAttribute(Position.KEY_IGNITION)) { - ignition = position.getBoolean(Position.KEY_IGNITION); - } - - boolean generateEvent = false; - if (newState) { - if (newTime - oldTime >= tripsConfig.getMinimalTripDuration() - || distance >= tripsConfig.getMinimalTripDistance()) { - generateEvent = true; - } - } else { - if (newTime - oldTime >= tripsConfig.getMinimalParkingDuration() - || ignition != null && !ignition) { - generateEvent = true; - } - } - - if (generateEvent) { - - String eventType = newState ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; - Event event = new Event(eventType, position); - - deviceState.setMotionTime(null); - deviceState.setMotionDistance(0); - - return Collections.singletonMap(event, position); - - } - } - } else { - deviceState.setMotionState(newState); - deviceState.setMotionTime(position.getFixTime()); - deviceState.setMotionDistance(position.getDouble(Position.KEY_TOTAL_DISTANCE)); - } - - return null; - } - @Override protected Map analyzePosition(Position position) { @@ -106,10 +67,19 @@ public class MotionEventHandler extends BaseEventHandler { return null; } - DeviceState deviceState = connectionManager.getDeviceState(deviceId); - var result = updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - connectionManager.setDeviceState(deviceId, deviceState); - return result; + MotionState state = MotionState.fromDevice(device); + MotionProcessor.updateState(state, position, position.getBoolean(Position.KEY_MOTION), tripsConfig); + if (state.isChanged()) { + state.toDevice(device); + try { + storage.updateObject(device, new Request( + new Columns.Include("motionState", "motionTime", "motionDistance"), + new Condition.Equals("id", "id"))); + } catch (StorageException e) { + LOGGER.warn("Update device motion error", e); + } + } + return state.getEvent() != null ? Collections.singletonMap(state.getEvent(), position) : null; } } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 3984299d7..c03b8eb7b 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -16,81 +16,50 @@ */ package org.traccar.handler.events; -import java.util.Collections; -import java.util.Map; - import io.netty.channel.ChannelHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.model.AttributeUtil; import org.traccar.helper.model.PositionUtil; import org.traccar.model.Device; -import org.traccar.session.ConnectionManager; -import org.traccar.session.DeviceState; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; +import org.traccar.session.state.OverspeedProcessor; +import org.traccar.session.state.OverspeedState; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; +import java.util.Collections; +import java.util.Map; @ChannelHandler.Sharable public class OverspeedEventHandler extends BaseEventHandler { - public static final String ATTRIBUTE_SPEED = "speed"; + private static final Logger LOGGER = LoggerFactory.getLogger(OverspeedEventHandler.class); - private final ConnectionManager connectionManager; private final CacheManager cacheManager; + private final Storage storage; private final long minimalDuration; private final boolean preferLowest; @Inject - public OverspeedEventHandler(Config config, ConnectionManager connectionManager, CacheManager cacheManager) { - this.connectionManager = connectionManager; + public OverspeedEventHandler( + Config config, CacheManager cacheManager, Storage storage) { this.cacheManager = cacheManager; + this.storage = storage; minimalDuration = config.getLong(Keys.EVENT_OVERSPEED_MINIMAL_DURATION) * 1000; preferLowest = config.getBoolean(Keys.EVENT_OVERSPEED_PREFER_LOWEST); } - public Map updateOverspeedState( - DeviceState deviceState, Position position, double speedLimit, long geofenceId) { - - boolean oldState = deviceState.getOverspeedState(); - if (oldState) { - boolean newState = position.getSpeed() > speedLimit; - if (newState) { - if (deviceState.getOverspeedTime() != null) { - long oldTime = deviceState.getOverspeedTime().getTime(); - long newTime = position.getFixTime().getTime(); - if (newTime - oldTime > minimalDuration) { - - Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); - event.set(ATTRIBUTE_SPEED, position.getSpeed()); - event.set(Position.KEY_SPEED_LIMIT, speedLimit); - event.setGeofenceId(deviceState.getOverspeedGeofenceId()); - - deviceState.setOverspeedTime(null); - deviceState.setOverspeedGeofenceId(0); - - return Collections.singletonMap(event, position); - - } - } - } else { - deviceState.setOverspeedState(false); - deviceState.setOverspeedTime(null); - deviceState.setOverspeedGeofenceId(0); - } - } else if (position != null && position.getSpeed() > speedLimit) { - deviceState.setOverspeedState(true); - deviceState.setOverspeedTime(position.getFixTime()); - deviceState.setOverspeedGeofenceId(geofenceId); - } - - return null; - } - @Override protected Map analyzePosition(Position position) { @@ -135,10 +104,19 @@ public class OverspeedEventHandler extends BaseEventHandler { return null; } - DeviceState deviceState = connectionManager.getDeviceState(deviceId); - var result = updateOverspeedState(deviceState, position, speedLimit, overspeedGeofenceId); - connectionManager.setDeviceState(deviceId, deviceState); - return result; + OverspeedState state = OverspeedState.fromDevice(device); + OverspeedProcessor.updateState(state, position, speedLimit, minimalDuration, overspeedGeofenceId); + if (state.isChanged()) { + state.toDevice(device); + try { + storage.updateObject(device, new Request( + new Columns.Include("overspeedState", "overspeedTime", "overspeedGeofenceId"), + new Condition.Equals("id", "id"))); + } catch (StorageException e) { + LOGGER.warn("Update device overspeed error", e); + } + } + return state.getEvent() != null ? Collections.singletonMap(state.getEvent(), position) : null; } } diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index f21e5ca84..147b0fd20 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -19,6 +19,7 @@ import java.util.Date; import java.util.List; import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.traccar.storage.QueryIgnore; import org.traccar.storage.StorageName; @@ -162,4 +163,82 @@ public class Device extends GroupedModel implements Disableable { this.expirationTime = expirationTime; } + private boolean motionState; + + @QueryIgnore + @JsonIgnore + public boolean getMotionState() { + return motionState; + } + + @JsonIgnore + public void setMotionState(boolean motionState) { + this.motionState = motionState; + } + + private Date motionTime; + + @QueryIgnore + @JsonIgnore + public Date getMotionTime() { + return motionTime; + } + + @JsonIgnore + public void setMotionTime(Date motionTime) { + this.motionTime = motionTime; + } + + private double motionDistance; + + @QueryIgnore + @JsonIgnore + public double getMotionDistance() { + return motionDistance; + } + + @JsonIgnore + public void setMotionDistance(double motionDistance) { + this.motionDistance = motionDistance; + } + + private boolean overspeedState; + + @QueryIgnore + @JsonIgnore + public boolean getOverspeedState() { + return overspeedState; + } + + @JsonIgnore + public void setOverspeedState(boolean overspeedState) { + this.overspeedState = overspeedState; + } + + private Date overspeedTime; + + @QueryIgnore + @JsonIgnore + public Date getOverspeedTime() { + return overspeedTime; + } + + @JsonIgnore + public void setOverspeedTime(Date overspeedTime) { + this.overspeedTime = overspeedTime; + } + + private long overspeedGeofenceId; + + @QueryIgnore + @JsonIgnore + public long getOverspeedGeofenceId() { + return overspeedGeofenceId; + } + + @JsonIgnore + public void setOverspeedGeofenceId(long overspeedGeofenceId) { + this.overspeedGeofenceId = overspeedGeofenceId; + } + } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 2bca00df7..57ed4d148 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -30,7 +30,6 @@ import org.traccar.api.security.PermissionsService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.geocoder.Geocoder; -import org.traccar.handler.events.MotionEventHandler; import org.traccar.helper.UnitsConverter; import org.traccar.helper.model.PositionUtil; import org.traccar.helper.model.UserUtil; @@ -43,7 +42,8 @@ import org.traccar.model.User; import org.traccar.reports.model.BaseReportItem; import org.traccar.reports.model.StopReportItem; import org.traccar.reports.model.TripReportItem; -import org.traccar.session.DeviceState; +import org.traccar.session.state.MotionProcessor; +import org.traccar.session.state.MotionState; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -350,17 +350,16 @@ public class ReportUtils { ArrayList positions = new ArrayList<>(positionCollection); if (!positions.isEmpty()) { boolean trips = reportClass.equals(TripReportItem.class); - MotionEventHandler motionHandler = new MotionEventHandler(null, null, tripsConfig); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(isMoving(positions, 0, tripsConfig)); + MotionState motionState = new MotionState(); + motionState.setMotionState(isMoving(positions, 0, tripsConfig)); - boolean detected = trips == deviceState.getMotionState(); + boolean detected = trips == motionState.getMotionState(); int startEventIndex = detected ? 0 : -1; int startNoEventIndex = -1; for (int i = 0; i < positions.size(); i++) { boolean motion = isMoving(positions, i, tripsConfig); - if (deviceState.getMotionState() != motion) { + if (motionState.getMotionState() != motion) { if (motion == trips) { startEventIndex = detected ? startEventIndex : i; startNoEventIndex = -1; @@ -369,7 +368,8 @@ public class ReportUtils { } } - if (motionHandler.updateMotionState(deviceState, positions.get(i), motion) != null) { + MotionProcessor.updateState(motionState, positions.get(i), motion, tripsConfig); + if (motionState.getEvent() != null) { if (motion == trips) { detected = true; startNoEventIndex = -1; diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index c826b99db..9e50c9ead 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -66,8 +66,6 @@ public class ConnectionManager implements BroadcastInterface { private final Map sessionsByDeviceId = new ConcurrentHashMap<>(); private final Map> sessionsByEndpoint = new ConcurrentHashMap<>(); - private final Map deviceStates = new ConcurrentHashMap<>(); - private final Config config; private final CacheManager cacheManager; private final Storage storage; @@ -275,14 +273,6 @@ public class ConnectionManager implements BroadcastInterface { updateDevice(true, device); } - public DeviceState getDeviceState(long deviceId) { - return deviceStates.computeIfAbsent(deviceId, x -> new DeviceState()); - } - - public void setDeviceState(long deviceId, DeviceState deviceState) { - deviceStates.put(deviceId, deviceState); - } - public synchronized void sendKeepalive() { for (Set userListeners : listeners.values()) { for (UpdateListener listener : userListeners) { diff --git a/src/main/java/org/traccar/session/DeviceState.java b/src/main/java/org/traccar/session/DeviceState.java deleted file mode 100644 index 7bf2a62ac..000000000 --- a/src/main/java/org/traccar/session/DeviceState.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@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.session; - -import java.util.Date; - -public class DeviceState { - - private boolean motionState; - - public void setMotionState(boolean motionState) { - this.motionState = motionState; - } - - public boolean getMotionState() { - return motionState; - } - - private Date motionTime; - - public Date getMotionTime() { - return motionTime; - } - - public void setMotionTime(Date motionTime) { - this.motionTime = motionTime; - } - - private double motionDistance; - - public double getMotionDistance() { - return motionDistance; - } - - public void setMotionDistance(double motionDistance) { - this.motionDistance = motionDistance; - } - - private boolean overspeedState; - - public void setOverspeedState(boolean overspeedState) { - this.overspeedState = overspeedState; - } - - public boolean getOverspeedState() { - return overspeedState; - } - - private Date overspeedTime; - - public Date getOverspeedTime() { - return overspeedTime; - } - - public void setOverspeedTime(Date overspeedTime) { - this.overspeedTime = overspeedTime; - } - - private long overspeedGeofenceId; - - public void setOverspeedGeofenceId(long overspeedGeofenceId) { - this.overspeedGeofenceId = overspeedGeofenceId; - } - - public long getOverspeedGeofenceId() { - return overspeedGeofenceId; - } - -} diff --git a/src/main/java/org/traccar/session/state/MotionProcessor.java b/src/main/java/org/traccar/session/state/MotionProcessor.java new file mode 100644 index 000000000..b9d706492 --- /dev/null +++ b/src/main/java/org/traccar/session/state/MotionProcessor.java @@ -0,0 +1,75 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.session.state; + +import org.traccar.model.Event; +import org.traccar.model.Position; +import org.traccar.reports.common.TripsConfig; + +public final class MotionProcessor { + + private MotionProcessor() { + } + + public static void updateState( + MotionState state, Position position, boolean newState, TripsConfig tripsConfig) { + + state.setEvent(null); + + boolean oldState = state.getMotionState(); + if (oldState == newState) { + if (state.getMotionTime() != null) { + long oldTime = state.getMotionTime().getTime(); + long newTime = position.getFixTime().getTime(); + + double distance = position.getDouble(Position.KEY_TOTAL_DISTANCE) - state.getMotionDistance(); + Boolean ignition = null; + if (tripsConfig.getUseIgnition() && position.hasAttribute(Position.KEY_IGNITION)) { + ignition = position.getBoolean(Position.KEY_IGNITION); + } + + boolean generateEvent = false; + if (newState) { + if (newTime - oldTime >= tripsConfig.getMinimalTripDuration() + || distance >= tripsConfig.getMinimalTripDistance()) { + generateEvent = true; + } + } else { + if (newTime - oldTime >= tripsConfig.getMinimalParkingDuration() + || ignition != null && !ignition) { + generateEvent = true; + } + } + + if (generateEvent) { + + String eventType = newState ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; + Event event = new Event(eventType, position); + + state.setMotionTime(null); + state.setMotionDistance(0); + state.setEvent(event); + + } + } + } else { + state.setMotionState(newState); + state.setMotionTime(position.getFixTime()); + state.setMotionDistance(position.getDouble(Position.KEY_TOTAL_DISTANCE)); + } + } + +} diff --git a/src/main/java/org/traccar/session/state/MotionState.java b/src/main/java/org/traccar/session/state/MotionState.java new file mode 100644 index 000000000..e3ce58ab2 --- /dev/null +++ b/src/main/java/org/traccar/session/state/MotionState.java @@ -0,0 +1,88 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.session.state; + +import org.traccar.model.Device; +import org.traccar.model.Event; + +import java.util.Date; + +public class MotionState { + + public static MotionState fromDevice(Device device) { + MotionState state = new MotionState(); + state.motionState = device.getMotionState(); + state.motionTime = device.getMotionTime(); + state.motionDistance = device.getMotionDistance(); + return state; + } + + public void toDevice(Device device) { + device.setMotionState(motionState); + device.setMotionTime(motionTime); + device.setMotionDistance(motionDistance); + } + + private boolean changed; + + public boolean isChanged() { + return changed; + } + + private boolean motionState; + + public boolean getMotionState() { + return motionState; + } + + public void setMotionState(boolean motionState) { + this.motionState = motionState; + changed = true; + } + + private Date motionTime; + + public Date getMotionTime() { + return motionTime; + } + + public void setMotionTime(Date motionTime) { + this.motionTime = motionTime; + changed = true; + } + + private double motionDistance; + + public double getMotionDistance() { + return motionDistance; + } + + public void setMotionDistance(double motionDistance) { + this.motionDistance = motionDistance; + changed = true; + } + + private Event event; + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + +} diff --git a/src/main/java/org/traccar/session/state/OverspeedProcessor.java b/src/main/java/org/traccar/session/state/OverspeedProcessor.java new file mode 100644 index 000000000..62f6a3de2 --- /dev/null +++ b/src/main/java/org/traccar/session/state/OverspeedProcessor.java @@ -0,0 +1,65 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.session.state; + +import org.traccar.model.Event; +import org.traccar.model.Position; + +public final class OverspeedProcessor { + + public static final String ATTRIBUTE_SPEED = "speed"; + + private OverspeedProcessor() { + } + + public static void updateState( + OverspeedState state, Position position, double speedLimit, long minimalDuration, long geofenceId) { + + state.setEvent(null); + + boolean oldState = state.getOverspeedState(); + if (oldState) { + boolean newState = position.getSpeed() > speedLimit; + if (newState) { + if (state.getOverspeedTime() != null) { + long oldTime = state.getOverspeedTime().getTime(); + long newTime = position.getFixTime().getTime(); + if (newTime - oldTime > minimalDuration) { + + Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position); + event.set(ATTRIBUTE_SPEED, position.getSpeed()); + event.set(Position.KEY_SPEED_LIMIT, speedLimit); + event.setGeofenceId(state.getOverspeedGeofenceId()); + + state.setOverspeedTime(null); + state.setOverspeedGeofenceId(0); + state.setEvent(event); + + } + } + } else { + state.setOverspeedState(false); + state.setOverspeedTime(null); + state.setOverspeedGeofenceId(0); + } + } else if (position != null && position.getSpeed() > speedLimit) { + state.setOverspeedState(true); + state.setOverspeedTime(position.getFixTime()); + state.setOverspeedGeofenceId(geofenceId); + } + } + +} diff --git a/src/main/java/org/traccar/session/state/OverspeedState.java b/src/main/java/org/traccar/session/state/OverspeedState.java new file mode 100644 index 000000000..340ede6d7 --- /dev/null +++ b/src/main/java/org/traccar/session/state/OverspeedState.java @@ -0,0 +1,88 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.session.state; + +import org.traccar.model.Device; +import org.traccar.model.Event; + +import java.util.Date; + +public class OverspeedState { + + public static OverspeedState fromDevice(Device device) { + OverspeedState state = new OverspeedState(); + state.overspeedState = device.getOverspeedState(); + state.overspeedTime = device.getOverspeedTime(); + state.overspeedGeofenceId = device.getOverspeedGeofenceId(); + return state; + } + + public void toDevice(Device device) { + device.setOverspeedState(overspeedState); + device.setOverspeedTime(overspeedTime); + device.setOverspeedGeofenceId(overspeedGeofenceId); + } + + private boolean changed; + + public boolean isChanged() { + return changed; + } + + private boolean overspeedState; + + public boolean getOverspeedState() { + return overspeedState; + } + + public void setOverspeedState(boolean overspeedState) { + this.overspeedState = overspeedState; + changed = true; + } + + private Date overspeedTime; + + public Date getOverspeedTime() { + return overspeedTime; + } + + public void setOverspeedTime(Date overspeedTime) { + this.overspeedTime = overspeedTime; + changed = true; + } + + private long overspeedGeofenceId; + + public long getOverspeedGeofenceId() { + return overspeedGeofenceId; + } + + public void setOverspeedGeofenceId(long overspeedGeofenceId) { + this.overspeedGeofenceId = overspeedGeofenceId; + changed = true; + } + + private Event event; + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + +} diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 0d4886429..22afbfa52 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -5,7 +5,8 @@ import org.traccar.BaseTest; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.reports.common.TripsConfig; -import org.traccar.session.DeviceState; +import org.traccar.session.state.MotionProcessor; +import org.traccar.session.state.MotionState; import java.text.DateFormat; import java.text.ParseException; @@ -28,57 +29,52 @@ public class MotionEventHandlerTest extends BaseTest { return position; } - private void verifyState(DeviceState deviceState, boolean state, long distance) { - assertEquals(state, deviceState.getMotionState()); - assertEquals(distance, deviceState.getMotionDistance(), 0.1); + private void verifyState(MotionState motionState, boolean state, long distance) { + assertEquals(state, motionState.getMotionState()); + assertEquals(distance, motionState.getMotionDistance(), 0.1); } @Test public void testMotionWithPosition() throws ParseException { - MotionEventHandler motionEventHandler = new MotionEventHandler( - null, null, new TripsConfig(500, 300000, 300000, 0, false, false, 0.01)); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false, 0.01); - DeviceState deviceState = new DeviceState(); + MotionState state = new MotionState(); - Position position = position("2017-01-01 00:00:00", false, 0, null); - assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); - verifyState(deviceState, false, 0); + MotionProcessor.updateState(state, position("2017-01-01 00:00:00", false, 0, null), false, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, false, 0); - position = position("2017-01-01 00:02:00", true, 100, null); - assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); - verifyState(deviceState, true, 100); + MotionProcessor.updateState(state, position("2017-01-01 00:02:00", true, 100, null), true, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, true, 100); - position = position("2017-01-01 00:02:00", true, 700, null); - var events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - assertEquals(Event.TYPE_DEVICE_MOVING, events.keySet().iterator().next().getType()); - verifyState(deviceState, true, 0); + MotionProcessor.updateState(state, position("2017-01-01 00:02:00", true, 700, null), true, tripsConfig); + assertEquals(Event.TYPE_DEVICE_MOVING, state.getEvent().getType()); + verifyState(state, true, 0); - position = position("2017-01-01 00:03:00", false, 700, null); - assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); - verifyState(deviceState, false, 700); + MotionProcessor.updateState(state, position("2017-01-01 00:03:00", false, 700, null), false, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, false, 700); - position = position("2017-01-01 00:10:00", false, 700, null); - events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - assertEquals(Event.TYPE_DEVICE_STOPPED, events.keySet().iterator().next().getType()); - verifyState(deviceState, false, 0); + MotionProcessor.updateState(state, position("2017-01-01 00:10:00", false, 700, null), false, tripsConfig); + assertEquals(Event.TYPE_DEVICE_STOPPED, state.getEvent().getType()); + verifyState(state, false, 0); } @Test public void testStopWithPositionIgnition() throws ParseException { - MotionEventHandler motionEventHandler = new MotionEventHandler( - null, null, new TripsConfig(500, 300000, 300000, 0, true, false, 0.01)); + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, true, false, 0.01); - DeviceState deviceState = new DeviceState(); - deviceState.setMotionState(true); + MotionState state = new MotionState(); + state.setMotionState(true); - Position position = position("2017-01-01 00:00:00", false, 100, true); - assertNull(motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION))); - verifyState(deviceState, false, 100); + MotionProcessor.updateState(state, position("2017-01-01 00:00:00", false, 100, true), false, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, false, 100); - position = position("2017-01-01 00:02:00", false, 100, false); - var events = motionEventHandler.updateMotionState(deviceState, position, position.getBoolean(Position.KEY_MOTION)); - assertEquals(Event.TYPE_DEVICE_STOPPED, events.keySet().iterator().next().getType()); - verifyState(deviceState, false, 0); + MotionProcessor.updateState(state, position("2017-01-01 00:02:00", false, 100, false), false, tripsConfig); + assertEquals(Event.TYPE_DEVICE_STOPPED, state.getEvent().getType()); + verifyState(state, false, 0); } } diff --git a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java index bbddbae72..ee18ee052 100644 --- a/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/OverspeedEventHandlerTest.java @@ -2,11 +2,10 @@ package org.traccar.handler.events; import org.junit.Test; import org.traccar.BaseTest; -import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; -import org.traccar.session.DeviceState; +import org.traccar.session.state.OverspeedProcessor; +import org.traccar.session.state.OverspeedState; import java.text.DateFormat; import java.text.ParseException; @@ -28,43 +27,36 @@ public class OverspeedEventHandlerTest extends BaseTest { return position; } - private void verifyState(DeviceState deviceState, boolean state, long geofenceId) { - assertEquals(state, deviceState.getOverspeedState()); - assertEquals(geofenceId, deviceState.getOverspeedGeofenceId()); + private void verifyState(OverspeedState overspeedState, boolean state, long geofenceId) { + assertEquals(state, overspeedState.getOverspeedState()); + assertEquals(geofenceId, overspeedState.getOverspeedGeofenceId()); } private void testOverspeedWithPosition(long geofenceId) throws ParseException { - Config config = new Config(); - config.setString(Keys.EVENT_OVERSPEED_MINIMAL_DURATION, String.valueOf(15)); - config.setString(Keys.EVENT_OVERSPEED_PREFER_LOWEST, String.valueOf(false)); - OverspeedEventHandler overspeedEventHandler = new OverspeedEventHandler(config, null, null); + OverspeedState state = new OverspeedState(); - DeviceState deviceState = new DeviceState(); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:00", 50), 40, 15000, geofenceId); + assertNull(state.getEvent()); + verifyState(state, true, geofenceId); - Position position = position("2017-01-01 00:00:00", 50); - assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); - verifyState(deviceState, true, geofenceId); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:10", 55), 40, 15000, geofenceId); + assertNull(state.getEvent()); - position = position("2017-01-01 00:00:10", 55); - assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:20", 55), 40, 15000, geofenceId); + assertNotNull(state.getEvent()); + assertEquals(Event.TYPE_DEVICE_OVERSPEED, state.getEvent().getType()); + assertEquals(55, state.getEvent().getDouble("speed"), 0.1); + assertEquals(40, state.getEvent().getDouble("speedLimit"), 0.1); + assertEquals(geofenceId, state.getEvent().getGeofenceId()); + verifyState(state, true, 0); - position = position("2017-01-01 00:00:20", 55); - var events = overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId); - assertNotNull(events); - Event event = events.keySet().iterator().next(); - assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); - assertEquals(55, event.getDouble("speed"), 0.1); - assertEquals(40, event.getDouble("speedLimit"), 0.1); - assertEquals(geofenceId, event.getGeofenceId()); - verifyState(deviceState, true, 0); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:30", 55), 40, 15000, geofenceId); + assertNull(state.getEvent()); + verifyState(state, true, 0); - position = position("2017-01-01 00:00:30", 55); - assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); - verifyState(deviceState, true, 0); - - position = position("2017-01-01 00:00:30", 30); - assertNull(overspeedEventHandler.updateOverspeedState(deviceState, position, 40, geofenceId)); - verifyState(deviceState, false, 0); + OverspeedProcessor.updateState(state, position("2017-01-01 00:00:30", 30), 40, 15000, geofenceId); + assertNull(state.getEvent()); + verifyState(state, false, 0); } @Test -- cgit v1.2.3 From 706de3e02cde8daa0bce29dd2ff96703f17ff92a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 27 Sep 2022 08:37:44 -0700 Subject: Better PID decoding error --- src/main/java/org/traccar/protocol/CastelProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index c2b740c4c..4aa65245b 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -160,6 +160,9 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < count; i++) { int value; + if (!PID_LENGTH_MAP.containsKey(pids[i])) { + throw new RuntimeException(String.format("Unknown PID 0x%02x", pids[i])); + } switch (PID_LENGTH_MAP.get(pids[i])) { case 1: value = buf.readUnsignedByte(); -- cgit v1.2.3 From e7a5d1e1f4d7746e35dfac5b15078de03dc7bf79 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 27 Sep 2022 09:27:12 -0700 Subject: Support RFTRACK monitoring units --- setup/default.xml | 1 + .../java/org/traccar/protocol/RfTrackProtocol.java | 43 ++++++++ .../traccar/protocol/RfTrackProtocolDecoder.java | 115 +++++++++++++++++++++ .../protocol/RfTrackProtocolDecoderTest.java | 19 ++++ 4 files changed, 178 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/RfTrackProtocol.java create mode 100644 src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java create mode 100644 src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 098bdf95d..77561109c 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -287,5 +287,6 @@ 5242 5243 5244 + 5245 diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocol.java b/src/main/java/org/traccar/protocol/RfTrackProtocol.java new file mode 100644 index 000000000..d3b41e93e --- /dev/null +++ b/src/main/java/org/traccar/protocol/RfTrackProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.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; +import org.traccar.config.Config; + +import javax.inject.Inject; + +public class RfTrackProtocol extends BaseProtocol { + + @Inject + public RfTrackProtocol(Config config) { + addServer(new TrackerServer(config, getName(), false) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new HttpResponseEncoder()); + pipeline.addLast(new HttpRequestDecoder()); + pipeline.addLast(new HttpObjectAggregator(16384)); + pipeline.addLast(new RfTrackProtocolDecoder(RfTrackProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java new file mode 100644 index 000000000..540c3ce0b --- /dev/null +++ b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java @@ -0,0 +1,115 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.Unpooled; +import io.netty.channel.Channel; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.QueryStringDecoder; +import org.traccar.BaseHttpProtocolDecoder; +import org.traccar.Protocol; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; +import org.traccar.session.DeviceSession; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonObject; +import java.io.StringReader; +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { + + public RfTrackProtocolDecoder(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.content().toString(StandardCharsets.US_ASCII), false); + Map> params = decoder.parameters(); + + Position position = new Position(getProtocolName()); + Network network = new Network(); + + for (Map.Entry> entry : params.entrySet()) { + for (String value : entry.getValue()) { + switch (entry.getKey()) { + case "i": + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); + if (deviceSession == null) { + sendResponse(channel, HttpResponseStatus.BAD_REQUEST); + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + break; + case "v": + position.set(Position.KEY_VERSION_FW, value); + break; + case "t": + position.setDeviceTime(new Date(Long.parseLong(value))); + break; + case "bat": + position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(value) & 0xff); + break; + case "gps": + JsonObject location = Json.createReader(new StringReader(value)).readObject(); + position.setValid(true); + position.setAccuracy(location.getJsonNumber("a").doubleValue()); + position.setLongitude(location.getJsonNumber("x").doubleValue()); + position.setLatitude(location.getJsonNumber("y").doubleValue()); + position.setAltitude(location.getJsonNumber("z").doubleValue()); + position.setFixTime(new Date(location.getJsonNumber("t").longValue())); + break; + case "gsm": + JsonObject cellInfo = Json.createReader(new StringReader(value)).readObject(); + int mcc = cellInfo.getInt("c"); + int mnc = cellInfo.getInt("n"); + JsonArray cells = cellInfo.getJsonArray("b"); + for (int i = 0; i < cells.size(); i++) { + JsonObject cell = cells.getJsonObject(i); + network.addCellTower(CellTower.from( + mcc, mnc, cell.getInt("l"), cell.getInt("c"), cell.getInt("b"))); + } + break; + default: + break; + } + } + } + + if (position.getFixTime() == null) { + getLastLocation(position, position.getDeviceTime()); + } + + if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { + position.setNetwork(network); + } + + sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer("{}", StandardCharsets.UTF_8)); + return position; + } + +} diff --git a/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java new file mode 100644 index 000000000..19a654fa6 --- /dev/null +++ b/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java @@ -0,0 +1,19 @@ +package org.traccar.protocol; + +import io.netty.handler.codec.http.HttpMethod; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class RfTrackProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new RfTrackProtocolDecoder(null)); + + verifyPosition(decoder, request(HttpMethod.POST, "/deviceDataUpload.do", + buffer("gsm={\"n\":0,\"b\":[{\"l\":6166,\"b\":19,\"c\":21423},{\"l\":6166,\"b\":18,\"c\":21416},{\"l\":6166,\"b\":17,\"c\":21383},{\"l\":6166,\"b\":13,\"c\":21422},{\"l\":6166,\"b\":13,\"c\":21435},{\"l\":6169,\"b\":11,\"c\":21311}],\"c\":460}&wifi=[{\"l\":-49,\"t\":\"lianqin20\"}]&mt=1073709094&i=358477047125172&gps={\"a\":30.0,\"y\":31.251563,\"s\":4,\"t\":1589764496654,\"z\":0.0,\"x\":121.360346}&dbm=-53&td=1589720501123&rc=0&bar=1001.85065&u_ids=[8441644.1,53036.1]&t=1589764500713&bat=12380&v=T2.142.2_2.0_R03&i_ids=[4247328.1,53036.1,10522408.1]&idt=140736414711817&id=39163"))); + + } + +} -- cgit v1.2.3 From f358feda0b0294e403dafd118714ab24b7a8afde Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 28 Sep 2022 06:57:11 -0700 Subject: Add table for command queue --- schema/changelog-5.4.xml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/schema/changelog-5.4.xml b/schema/changelog-5.4.xml index f3a13ef59..e69bc5fab 100644 --- a/schema/changelog-5.4.xml +++ b/schema/changelog-5.4.xml @@ -17,6 +17,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 257ee673e08d2d4080d156079ce7b62752f1476d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 28 Sep 2022 07:13:11 -0700 Subject: Queued command model --- src/main/java/org/traccar/model/BaseCommand.java | 40 +++++++++++++++++++ src/main/java/org/traccar/model/Command.java | 29 +------------- src/main/java/org/traccar/model/QueuedCommand.java | 45 ++++++++++++++++++++++ 3 files changed, 87 insertions(+), 27 deletions(-) create mode 100644 src/main/java/org/traccar/model/BaseCommand.java create mode 100644 src/main/java/org/traccar/model/QueuedCommand.java diff --git a/src/main/java/org/traccar/model/BaseCommand.java b/src/main/java/org/traccar/model/BaseCommand.java new file mode 100644 index 000000000..16df9c126 --- /dev/null +++ b/src/main/java/org/traccar/model/BaseCommand.java @@ -0,0 +1,40 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.model; + +public class BaseCommand extends Message { + + private String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + private boolean textChannel; + + public boolean getTextChannel() { + return textChannel; + } + + public void setTextChannel(boolean textChannel) { + this.textChannel = textChannel; + } + +} diff --git a/src/main/java/org/traccar/model/Command.java b/src/main/java/org/traccar/model/Command.java index 49486bdbc..4ea619e95 100644 --- a/src/main/java/org/traccar/model/Command.java +++ b/src/main/java/org/traccar/model/Command.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@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,7 +22,7 @@ import org.traccar.storage.StorageName; @StorageName("tc_commands") @JsonIgnoreProperties(ignoreUnknown = true) -public class Command extends Message implements Cloneable { +public class Command extends BaseCommand { public static final String TYPE_CUSTOM = "custom"; public static final String TYPE_IDENTIFICATION = "deviceIdentification"; @@ -84,21 +84,6 @@ public class Command extends Message implements Cloneable { public static final String KEY_SERVER = "server"; public static final String KEY_PORT = "port"; - @Override - public Command clone() throws CloneNotSupportedException { - return (Command) super.clone(); - } - - private boolean textChannel; - - public boolean getTextChannel() { - return textChannel; - } - - public void setTextChannel(boolean textChannel) { - this.textChannel = textChannel; - } - @QueryIgnore @Override public long getDeviceId() { @@ -111,14 +96,4 @@ public class Command extends Message implements Cloneable { super.setDeviceId(deviceId); } - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - } diff --git a/src/main/java/org/traccar/model/QueuedCommand.java b/src/main/java/org/traccar/model/QueuedCommand.java new file mode 100644 index 000000000..fff77a22b --- /dev/null +++ b/src/main/java/org/traccar/model/QueuedCommand.java @@ -0,0 +1,45 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.model; + +import org.traccar.storage.StorageName; + +import java.util.HashMap; + +@StorageName("tc_commands_queue") +public class QueuedCommand extends BaseCommand { + + public static QueuedCommand fromCommand(Command command) { + QueuedCommand queuedCommand = new QueuedCommand(); + queuedCommand.setDeviceId(command.getDeviceId()); + queuedCommand.setType(command.getType()); + queuedCommand.setDescription(command.getDescription()); + queuedCommand.setTextChannel(command.getTextChannel()); + queuedCommand.setAttributes(new HashMap<>(command.getAttributes())); + return queuedCommand; + } + + public Command toCommand() { + Command command = new Command(); + command.setDeviceId(getDeviceId()); + command.setType(getType()); + command.setDescription(getDescription()); + command.setTextChannel(getTextChannel()); + command.setAttributes(new HashMap<>(getAttributes())); + return command; + } + +} -- cgit v1.2.3 From 0f74a9c4452a044ff619f0b24d69b41aece09b94 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 29 Sep 2022 17:17:42 -0700 Subject: Remove queueing parameter --- src/main/java/org/traccar/config/Keys.java | 8 -------- src/main/java/org/traccar/database/CommandsManager.java | 12 ++++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index ea394d914..1da01518c 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -779,14 +779,6 @@ public final class Keys { "event.forward.header", List.of(KeyType.CONFIG)); - /** - * Enable commands queuing when devices are offline. Commands are buffered in memory only, so restarting service - * will clear the buffer. - */ - public static final ConfigKey COMMANDS_QUEUEING = new BooleanConfigKey( - "commands.queueing", - List.of(KeyType.CONFIG)); - /** * Root folder for all template files. */ diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 2967b8abd..49eda79b2 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -18,8 +18,6 @@ package org.traccar.database; import org.traccar.BaseProtocol; import org.traccar.ServerManager; -import org.traccar.config.Config; -import org.traccar.config.Keys; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; @@ -55,22 +53,22 @@ public class CommandsManager { private final SmsManager smsManager; private final ConnectionManager connectionManager; - private final boolean queueing; - @Inject public CommandsManager( Storage storage, ServerManager serverManager, @Nullable SmsManager smsManager, - ConnectionManager connectionManager, Config config) { + ConnectionManager connectionManager) { this.storage = storage; this.serverManager = serverManager; this.smsManager = smsManager; this.connectionManager = connectionManager; - queueing = config.getBoolean(Keys.COMMANDS_QUEUEING); } public boolean sendCommand(Command command) throws Exception { long deviceId = command.getDeviceId(); if (command.getTextChannel()) { + if (smsManager == null) { + throw new RuntimeException("SMS not configured"); + } Device device = storage.getObject(Device.class, new Request( new Columns.Include("positionId", "phone"), new Condition.Equals("id", "id", deviceId))); Position position = storage.getObject(Position.class, new Request( @@ -92,8 +90,6 @@ public class CommandsManager { getDeviceQueue(deviceId).add(command); return false; } - } else if (!queueing) { - throw new RuntimeException("Device is not online"); } else { getDeviceQueue(deviceId).add(command); return false; -- cgit v1.2.3 From 7246644f393f9a373f4e3f2be846500e8456a286 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 29 Sep 2022 17:23:16 -0700 Subject: Simplify commands logic --- src/main/java/org/traccar/database/CommandsManager.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 49eda79b2..945fb13af 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -83,13 +83,8 @@ public class CommandsManager { } } else { DeviceSession deviceSession = connectionManager.getDeviceSession(deviceId); - if (deviceSession != null) { - if (deviceSession.supportsLiveCommands()) { - deviceSession.sendCommand(command); - } else { - getDeviceQueue(deviceId).add(command); - return false; - } + if (deviceSession != null && deviceSession.supportsLiveCommands()) { + deviceSession.sendCommand(command); } else { getDeviceQueue(deviceId).add(command); return false; -- cgit v1.2.3 From e7bd758824386e4f77f78ceca57675ef7934435a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 29 Sep 2022 17:43:30 -0700 Subject: Use DB command queue --- .../java/org/traccar/database/CommandsManager.java | 62 ++++++---------------- 1 file changed, 17 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 945fb13af..d56b4d472 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -21,33 +21,27 @@ import org.traccar.ServerManager; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.model.QueuedCommand; import org.traccar.session.ConnectionManager; import org.traccar.session.DeviceSession; import org.traccar.sms.SmsManager; import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Limit; +import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; -import java.util.ArrayList; import java.util.Collection; -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; @Singleton public class CommandsManager { - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - private final Map> deviceQueues = new ConcurrentHashMap<>(); - private final Storage storage; private final ServerManager serverManager; private final SmsManager smsManager; @@ -86,54 +80,32 @@ public class CommandsManager { if (deviceSession != null && deviceSession.supportsLiveCommands()) { deviceSession.sendCommand(command); } else { - getDeviceQueue(deviceId).add(command); + storage.addObject(QueuedCommand.fromCommand(command), new Request(new Columns.Exclude("id"))); return false; } } return true; } - private Queue getDeviceQueue(long deviceId) { - Queue deviceQueue; - try { - lock.readLock().lock(); - deviceQueue = deviceQueues.get(deviceId); - } finally { - lock.readLock().unlock(); - } - if (deviceQueue != null) { - return deviceQueue; - } else { - try { - lock.writeLock().lock(); - return deviceQueues.computeIfAbsent(deviceId, key -> new ConcurrentLinkedQueue<>()); - } finally { - lock.writeLock().unlock(); - } - } - } - public Collection readQueuedCommands(long deviceId) { return readQueuedCommands(deviceId, Integer.MAX_VALUE); } public Collection readQueuedCommands(long deviceId, int count) { - Queue deviceQueue; try { - lock.readLock().lock(); - deviceQueue = deviceQueues.get(deviceId); - } finally { - lock.readLock().unlock(); - } - Collection result = new ArrayList<>(); - if (deviceQueue != null) { - Command command = deviceQueue.poll(); - while (command != null && result.size() < count) { - result.add(command); - command = deviceQueue.poll(); + var commands = storage.getObjects(QueuedCommand.class, new Request( + new Columns.All(), + new Condition.Equals("deviceId", "deviceId", deviceId), + new Order(false, "id"), + new Limit(count))); + for (var command : commands) { + storage.removeObject(QueuedCommand.class, new Request( + new Condition.Equals("id", "id", command.getId()))); } + return commands.stream().map(QueuedCommand::toCommand).collect(Collectors.toList()); + } catch (StorageException e) { + throw new RuntimeException(e); } - return result; } } -- cgit v1.2.3 From 0a853f2aa3556554acd0b43a5008c43c345fa300 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 29 Sep 2022 17:57:22 -0700 Subject: Synchronize queued commands --- .../org/traccar/broadcast/BroadcastInterface.java | 3 +++ .../org/traccar/broadcast/BroadcastMessage.java | 10 ++++++++++ .../broadcast/MulticastBroadcastService.java | 9 +++++++++ .../java/org/traccar/database/CommandsManager.java | 22 ++++++++++++++++++++-- 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/broadcast/BroadcastInterface.java b/src/main/java/org/traccar/broadcast/BroadcastInterface.java index dddba68b6..673ebd8b8 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastInterface.java +++ b/src/main/java/org/traccar/broadcast/BroadcastInterface.java @@ -31,6 +31,9 @@ public interface BroadcastInterface { default void updateEvent(boolean local, long userId, Event event) { } + default void updateCommand(boolean local, long deviceId) { + } + default void invalidateObject(boolean local, Class clazz, long id) { } diff --git a/src/main/java/org/traccar/broadcast/BroadcastMessage.java b/src/main/java/org/traccar/broadcast/BroadcastMessage.java index 3e22be7e0..985848d04 100644 --- a/src/main/java/org/traccar/broadcast/BroadcastMessage.java +++ b/src/main/java/org/traccar/broadcast/BroadcastMessage.java @@ -63,6 +63,16 @@ public class BroadcastMessage { this.event = event; } + private Long commandDeviceId; + + public Long getCommandDeviceId() { + return commandDeviceId; + } + + public void setCommandDeviceId(Long commandDeviceId) { + this.commandDeviceId = commandDeviceId; + } + private Map changes; public Map getChanges() { diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java index be65b7826..b1b66f1e3 100644 --- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java +++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java @@ -102,6 +102,13 @@ public class MulticastBroadcastService implements BroadcastService { sendMessage(message); } + @Override + public void updateCommand(boolean local, long deviceId) { + BroadcastMessage message = new BroadcastMessage(); + message.setCommandDeviceId(deviceId); + sendMessage(message); + } + @Override public void invalidateObject(boolean local, Class clazz, long id) { BroadcastMessage message = new BroadcastMessage(); @@ -136,6 +143,8 @@ public class MulticastBroadcastService implements BroadcastService { listeners.forEach(listener -> listener.updatePosition(false, message.getPosition())); } else if (message.getUserId() != null && message.getEvent() != null) { listeners.forEach(listener -> listener.updateEvent(false, message.getUserId(), message.getEvent())); + } else if (message.getCommandDeviceId() != null) { + listeners.forEach(listener -> listener.updateCommand(false, message.getCommandDeviceId())); } else if (message.getChanges() != null) { var iterator = message.getChanges().entrySet().iterator(); if (iterator.hasNext()) { diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index d56b4d472..53040ad53 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -18,6 +18,8 @@ package org.traccar.database; import org.traccar.BaseProtocol; import org.traccar.ServerManager; +import org.traccar.broadcast.BroadcastInterface; +import org.traccar.broadcast.BroadcastService; import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; @@ -40,21 +42,24 @@ import java.util.Collection; import java.util.stream.Collectors; @Singleton -public class CommandsManager { +public class CommandsManager implements BroadcastInterface { private final Storage storage; private final ServerManager serverManager; private final SmsManager smsManager; private final ConnectionManager connectionManager; + private final BroadcastService broadcastService; @Inject public CommandsManager( Storage storage, ServerManager serverManager, @Nullable SmsManager smsManager, - ConnectionManager connectionManager) { + ConnectionManager connectionManager, BroadcastService broadcastService) { this.storage = storage; this.serverManager = serverManager; this.smsManager = smsManager; this.connectionManager = connectionManager; + this.broadcastService = broadcastService; + broadcastService.registerListener(this); } public boolean sendCommand(Command command) throws Exception { @@ -81,6 +86,7 @@ public class CommandsManager { deviceSession.sendCommand(command); } else { storage.addObject(QueuedCommand.fromCommand(command), new Request(new Columns.Exclude("id"))); + broadcastService.updateCommand(true, deviceId); return false; } } @@ -108,4 +114,16 @@ public class CommandsManager { } } + @Override + public void updateCommand(boolean local, long deviceId) { + if (!local) { + DeviceSession deviceSession = connectionManager.getDeviceSession(deviceId); + if (deviceSession != null && deviceSession.supportsLiveCommands()) { + for (Command command : readQueuedCommands(deviceId)) { + deviceSession.sendCommand(command); + } + } + } + } + } -- cgit v1.2.3 From 63a8bb747e92cc98d64bad59464922a9f6be5867 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 1 Oct 2022 19:24:15 -0700 Subject: Enable iOS sound --- src/main/java/org/traccar/notificators/NotificatorFirebase.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java index 3723a4226..5ce2cbc0b 100644 --- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java +++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java @@ -21,6 +21,8 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.messaging.AndroidConfig; import com.google.firebase.messaging.AndroidNotification; +import com.google.firebase.messaging.ApnsConfig; +import com.google.firebase.messaging.Aps; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.FirebaseMessagingException; import com.google.firebase.messaging.MulticastMessage; @@ -79,6 +81,11 @@ public class NotificatorFirebase implements Notificator { .setSound("default") .build()) .build()) + .setApnsConfig(ApnsConfig.builder() + .setAps(Aps.builder() + .setSound("default") + .build()) + .build()) .addAllTokens(registrationTokens) .putData("eventId", String.valueOf(event.getId())) .build(); -- cgit v1.2.3 From ae3eddba7e0a6688807f71d2c290618d1c49da05 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 08:39:06 -0700 Subject: Use singletons where possible --- src/main/java/org/traccar/MainEventHandler.java | 9 +++++---- src/main/java/org/traccar/MainModule.java | 9 ++++++++- src/main/java/org/traccar/WebDataHandler.java | 2 ++ src/main/java/org/traccar/api/CorsResponseFilter.java | 2 ++ src/main/java/org/traccar/api/security/LoginService.java | 2 ++ src/main/java/org/traccar/api/signature/CryptoManager.java | 2 ++ src/main/java/org/traccar/api/signature/TokenManager.java | 2 ++ src/main/java/org/traccar/database/MediaManager.java | 2 ++ src/main/java/org/traccar/database/NotificationManager.java | 2 ++ src/main/java/org/traccar/handler/ComputedAttributesHandler.java | 2 ++ src/main/java/org/traccar/handler/CopyAttributesHandler.java | 2 ++ src/main/java/org/traccar/handler/DefaultDataHandler.java | 2 ++ src/main/java/org/traccar/handler/DistanceHandler.java | 2 ++ src/main/java/org/traccar/handler/EngineHoursHandler.java | 2 ++ src/main/java/org/traccar/handler/FilterHandler.java | 2 ++ src/main/java/org/traccar/handler/HemisphereHandler.java | 2 ++ src/main/java/org/traccar/handler/MotionHandler.java | 2 ++ src/main/java/org/traccar/handler/RemoteAddressHandler.java | 2 ++ src/main/java/org/traccar/handler/SpeedLimitHandler.java | 2 ++ src/main/java/org/traccar/handler/TimeHandler.java | 2 ++ src/main/java/org/traccar/handler/events/AlertEventHandler.java | 2 ++ .../java/org/traccar/handler/events/BehaviorEventHandler.java | 2 ++ .../org/traccar/handler/events/CommandResultEventHandler.java | 2 ++ src/main/java/org/traccar/handler/events/DriverEventHandler.java | 2 ++ src/main/java/org/traccar/handler/events/FuelEventHandler.java | 2 ++ .../java/org/traccar/handler/events/GeofenceEventHandler.java | 2 ++ .../java/org/traccar/handler/events/IgnitionEventHandler.java | 2 ++ .../java/org/traccar/handler/events/MaintenanceEventHandler.java | 2 ++ src/main/java/org/traccar/handler/events/MediaEventHandler.java | 2 ++ src/main/java/org/traccar/handler/events/MotionEventHandler.java | 2 ++ .../java/org/traccar/handler/events/OverspeedEventHandler.java | 2 ++ .../java/org/traccar/notification/NotificationFormatter.java | 2 ++ .../java/org/traccar/notification/TextTemplateFormatter.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorMail.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorPushover.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorSms.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorTelegram.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorTraccar.java | 2 ++ src/main/java/org/traccar/notificators/NotificatorWeb.java | 8 +++----- src/main/java/org/traccar/reports/common/ReportUtils.java | 2 ++ src/main/java/org/traccar/reports/common/TripsConfig.java | 2 ++ src/main/java/org/traccar/web/WebServer.java | 2 -- 42 files changed, 92 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 52eb43faf..17bcad0dd 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -16,6 +16,7 @@ package org.traccar; import io.netty.channel.Channel; +import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.socket.DatagramChannel; @@ -23,7 +24,6 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.StatisticsManager; @@ -41,11 +41,14 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; +@Singleton +@ChannelHandler.Sharable public class MainEventHandler extends ChannelInboundHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(MainEventHandler.class); @@ -57,17 +60,15 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { private final Storage storage; private final ConnectionManager connectionManager; private final StatisticsManager statisticsManager; - private final BroadcastService broadcastService; @Inject public MainEventHandler( Config config, CacheManager cacheManager, Storage storage, ConnectionManager connectionManager, - StatisticsManager statisticsManager, BroadcastService broadcastService) { + StatisticsManager statisticsManager) { this.cacheManager = cacheManager; this.storage = storage; this.connectionManager = connectionManager; this.statisticsManager = statisticsManager; - this.broadcastService = broadcastService; String connectionlessProtocolList = config.getString(Keys.STATUS_IGNORE_OFFLINE); if (connectionlessProtocolList != null) { connectionlessProtocols.addAll(Arrays.asList(connectionlessProtocolList.split("[, ]"))); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 94669915b..c4cda578e 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -99,10 +99,11 @@ public class MainModule extends AbstractModule { protected void configure() { bindConstant().annotatedWith(Names.named("configFile")).to(configFile); bind(Config.class).asEagerSingleton(); - bind(Storage.class).to(DatabaseStorage.class); + bind(Storage.class).to(DatabaseStorage.class).in(Scopes.SINGLETON); bind(Timer.class).to(HashedWheelTimer.class).in(Scopes.SINGLETON); } + @Singleton @Provides public static ObjectMapper provideObjectMapper(Config config) { ObjectMapper objectMapper = new ObjectMapper(); @@ -114,6 +115,7 @@ public class MainModule extends AbstractModule { return objectMapper; } + @Singleton @Provides public static Client provideClient(ObjectMapperContextResolver objectMapperContextResolver) { return ClientBuilder.newClient().register(objectMapperContextResolver); @@ -130,6 +132,7 @@ public class MainModule extends AbstractModule { return null; } + @Singleton @Provides public static MailManager provideMailManager(Config config, StatisticsManager statisticsManager) { if (config.getBoolean(Keys.MAIL_DEBUG)) { @@ -265,6 +268,7 @@ public class MainModule extends AbstractModule { return null; } + @Singleton @Provides public static GeolocationHandler provideGeolocationHandler( Config config, @Nullable GeolocationProvider geolocationProvider, CacheManager cacheManager, @@ -275,6 +279,7 @@ public class MainModule extends AbstractModule { return null; } + @Singleton @Provides public static GeocoderHandler provideGeocoderHandler( Config config, @Nullable Geocoder geocoder, CacheManager cacheManager) { @@ -284,6 +289,7 @@ public class MainModule extends AbstractModule { return null; } + @Singleton @Provides public static SpeedLimitHandler provideSpeedLimitHandler(@Nullable SpeedLimitProvider speedLimitProvider) { if (speedLimitProvider != null) { @@ -302,6 +308,7 @@ public class MainModule extends AbstractModule { return new NullBroadcastService(); } + @Singleton @Provides public static EventForwarder provideEventForwarder(Config config, Client client, CacheManager cacheManager) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index d0aa32e53..9b26c8875 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -33,6 +33,7 @@ import org.traccar.model.Group; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -52,6 +53,7 @@ import java.util.TimeZone; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +@Singleton @ChannelHandler.Sharable public class WebDataHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/api/CorsResponseFilter.java b/src/main/java/org/traccar/api/CorsResponseFilter.java index 5375e207f..67d0341a1 100644 --- a/src/main/java/org/traccar/api/CorsResponseFilter.java +++ b/src/main/java/org/traccar/api/CorsResponseFilter.java @@ -20,11 +20,13 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import java.io.IOException; +@Singleton public class CorsResponseFilter implements ContainerResponseFilter { private final String allowed; diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 1e82a4cf2..32487f06b 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -28,9 +28,11 @@ import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.security.GeneralSecurityException; +@Singleton public class LoginService { private final Storage storage; diff --git a/src/main/java/org/traccar/api/signature/CryptoManager.java b/src/main/java/org/traccar/api/signature/CryptoManager.java index 8a3e7704c..249d5bd97 100644 --- a/src/main/java/org/traccar/api/signature/CryptoManager.java +++ b/src/main/java/org/traccar/api/signature/CryptoManager.java @@ -21,6 +21,7 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.KeyPair; @@ -33,6 +34,7 @@ import java.security.spec.ECGenParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; +@Singleton public class CryptoManager { private final Storage storage; diff --git a/src/main/java/org/traccar/api/signature/TokenManager.java b/src/main/java/org/traccar/api/signature/TokenManager.java index a352ecc10..6a0d90b40 100644 --- a/src/main/java/org/traccar/api/signature/TokenManager.java +++ b/src/main/java/org/traccar/api/signature/TokenManager.java @@ -21,11 +21,13 @@ import org.apache.commons.codec.binary.Base64; import org.traccar.storage.StorageException; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.security.GeneralSecurityException; import java.util.Date; import java.util.concurrent.TimeUnit; +@Singleton public class TokenManager { private static final int DEFAULT_EXPIRATION_DAYS = 7; diff --git a/src/main/java/org/traccar/database/MediaManager.java b/src/main/java/org/traccar/database/MediaManager.java index 2b3e3e1ee..c1ef810ee 100644 --- a/src/main/java/org/traccar/database/MediaManager.java +++ b/src/main/java/org/traccar/database/MediaManager.java @@ -22,6 +22,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -34,6 +35,7 @@ import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; +@Singleton public class MediaManager { private static final Logger LOGGER = LoggerFactory.getLogger(MediaManager.class); diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 5be627f2a..5ea89fcac 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -36,11 +36,13 @@ import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; +@Singleton public class NotificationManager { private static final Logger LOGGER = LoggerFactory.getLogger(NotificationManager.class); diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index 82ac4e804..c9f1f63d7 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -40,7 +40,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class ComputedAttributesHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java index 1fa47cfaa..e5c9bc29a 100644 --- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java +++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java @@ -25,7 +25,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class CopyAttributesHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/DefaultDataHandler.java b/src/main/java/org/traccar/handler/DefaultDataHandler.java index f6a20628b..89255a5fe 100644 --- a/src/main/java/org/traccar/handler/DefaultDataHandler.java +++ b/src/main/java/org/traccar/handler/DefaultDataHandler.java @@ -25,7 +25,9 @@ import org.traccar.storage.query.Columns; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class DefaultDataHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/DistanceHandler.java b/src/main/java/org/traccar/handler/DistanceHandler.java index 87c4a81c9..30dc9ff2b 100644 --- a/src/main/java/org/traccar/handler/DistanceHandler.java +++ b/src/main/java/org/traccar/handler/DistanceHandler.java @@ -25,9 +25,11 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; import java.math.BigDecimal; import java.math.RoundingMode; +@Singleton @ChannelHandler.Sharable public class DistanceHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/EngineHoursHandler.java b/src/main/java/org/traccar/handler/EngineHoursHandler.java index 54a1a0c25..c10fe9064 100644 --- a/src/main/java/org/traccar/handler/EngineHoursHandler.java +++ b/src/main/java/org/traccar/handler/EngineHoursHandler.java @@ -22,7 +22,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class EngineHoursHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 37f5cd566..f09cb16a3 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -35,8 +35,10 @@ import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Date; +@Singleton @ChannelHandler.Sharable public class FilterHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/HemisphereHandler.java b/src/main/java/org/traccar/handler/HemisphereHandler.java index f760457a3..ccbde9fe5 100644 --- a/src/main/java/org/traccar/handler/HemisphereHandler.java +++ b/src/main/java/org/traccar/handler/HemisphereHandler.java @@ -22,7 +22,9 @@ import org.traccar.config.Keys; import org.traccar.model.Position; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class HemisphereHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/MotionHandler.java b/src/main/java/org/traccar/handler/MotionHandler.java index 25ee615c5..10312f9b3 100644 --- a/src/main/java/org/traccar/handler/MotionHandler.java +++ b/src/main/java/org/traccar/handler/MotionHandler.java @@ -22,7 +22,9 @@ import org.traccar.model.Position; import org.traccar.reports.common.TripsConfig; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class MotionHandler extends BaseDataHandler { diff --git a/src/main/java/org/traccar/handler/RemoteAddressHandler.java b/src/main/java/org/traccar/handler/RemoteAddressHandler.java index 809f67ca2..e18d34ef2 100644 --- a/src/main/java/org/traccar/handler/RemoteAddressHandler.java +++ b/src/main/java/org/traccar/handler/RemoteAddressHandler.java @@ -23,8 +23,10 @@ import org.traccar.config.Keys; import org.traccar.model.Position; import javax.inject.Inject; +import javax.inject.Singleton; import java.net.InetSocketAddress; +@Singleton @ChannelHandler.Sharable public class RemoteAddressHandler extends ChannelInboundHandlerAdapter { diff --git a/src/main/java/org/traccar/handler/SpeedLimitHandler.java b/src/main/java/org/traccar/handler/SpeedLimitHandler.java index 0469b9f16..0c6025999 100644 --- a/src/main/java/org/traccar/handler/SpeedLimitHandler.java +++ b/src/main/java/org/traccar/handler/SpeedLimitHandler.java @@ -24,7 +24,9 @@ import org.traccar.model.Position; import org.traccar.speedlimit.SpeedLimitProvider; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class SpeedLimitHandler extends ChannelInboundHandlerAdapter { diff --git a/src/main/java/org/traccar/handler/TimeHandler.java b/src/main/java/org/traccar/handler/TimeHandler.java index 439c076c7..c98b0bd4c 100644 --- a/src/main/java/org/traccar/handler/TimeHandler.java +++ b/src/main/java/org/traccar/handler/TimeHandler.java @@ -24,10 +24,12 @@ import org.traccar.config.Keys; import org.traccar.model.Position; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +@Singleton @ChannelHandler.Sharable public class TimeHandler extends ChannelInboundHandlerAdapter { diff --git a/src/main/java/org/traccar/handler/events/AlertEventHandler.java b/src/main/java/org/traccar/handler/events/AlertEventHandler.java index 75626ca6c..9f77df989 100644 --- a/src/main/java/org/traccar/handler/events/AlertEventHandler.java +++ b/src/main/java/org/traccar/handler/events/AlertEventHandler.java @@ -26,7 +26,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class AlertEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java index 3c2fa6a97..51bbd82d6 100644 --- a/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java +++ b/src/main/java/org/traccar/handler/events/BehaviorEventHandler.java @@ -24,9 +24,11 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Collections; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class BehaviorEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java index 858f84e09..772176e9c 100644 --- a/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java +++ b/src/main/java/org/traccar/handler/events/CommandResultEventHandler.java @@ -23,7 +23,9 @@ import org.traccar.model.Event; import org.traccar.model.Position; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class CommandResultEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/DriverEventHandler.java b/src/main/java/org/traccar/handler/events/DriverEventHandler.java index 1ad66ba64..51fdc0307 100644 --- a/src/main/java/org/traccar/handler/events/DriverEventHandler.java +++ b/src/main/java/org/traccar/handler/events/DriverEventHandler.java @@ -23,9 +23,11 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Collections; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class DriverEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/FuelEventHandler.java b/src/main/java/org/traccar/handler/events/FuelEventHandler.java index d5d4ab9be..462cc4223 100644 --- a/src/main/java/org/traccar/handler/events/FuelEventHandler.java +++ b/src/main/java/org/traccar/handler/events/FuelEventHandler.java @@ -25,8 +25,10 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class FuelEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index 70bdb84cb..b1be7e8ad 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -33,11 +33,13 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class GeofenceEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java index 3c5ac3545..b2e9a3325 100644 --- a/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/IgnitionEventHandler.java @@ -27,7 +27,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class IgnitionEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index be3e9bf8d..4fcfcd079 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -26,7 +26,9 @@ import org.traccar.model.Position; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton @ChannelHandler.Sharable public class MaintenanceEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/MediaEventHandler.java b/src/main/java/org/traccar/handler/events/MediaEventHandler.java index 5b9013fad..a49e08e8d 100644 --- a/src/main/java/org/traccar/handler/events/MediaEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MediaEventHandler.java @@ -20,10 +20,12 @@ import org.traccar.model.Event; import org.traccar.model.Position; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; +@Singleton @ChannelHandler.Sharable public class MediaEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 0777f353a..3511cf682 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -34,9 +34,11 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Collections; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class MotionEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index c03b8eb7b..3928fcc88 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -37,9 +37,11 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Collections; import java.util.Map; +@Singleton @ChannelHandler.Sharable public class OverspeedEventHandler extends BaseEventHandler { diff --git a/src/main/java/org/traccar/notification/NotificationFormatter.java b/src/main/java/org/traccar/notification/NotificationFormatter.java index fa244d9b4..9ee3b97b6 100644 --- a/src/main/java/org/traccar/notification/NotificationFormatter.java +++ b/src/main/java/org/traccar/notification/NotificationFormatter.java @@ -28,7 +28,9 @@ import org.traccar.model.User; import org.traccar.session.cache.CacheManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class NotificationFormatter { private final CacheManager cacheManager; diff --git a/src/main/java/org/traccar/notification/TextTemplateFormatter.java b/src/main/java/org/traccar/notification/TextTemplateFormatter.java index be894af96..444f4a7c2 100644 --- a/src/main/java/org/traccar/notification/TextTemplateFormatter.java +++ b/src/main/java/org/traccar/notification/TextTemplateFormatter.java @@ -30,6 +30,7 @@ import org.traccar.model.User; import org.traccar.storage.StorageException; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; @@ -37,6 +38,7 @@ import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.util.Locale; +@Singleton public class TextTemplateFormatter { private static final Logger LOGGER = LoggerFactory.getLogger(TextTemplateFormatter.class); diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java index 75571cfc4..19fde6756 100644 --- a/src/main/java/org/traccar/notificators/NotificatorMail.java +++ b/src/main/java/org/traccar/notificators/NotificatorMail.java @@ -24,8 +24,10 @@ import org.traccar.notification.MessageException; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; +import javax.inject.Singleton; import javax.mail.MessagingException; +@Singleton public class NotificatorMail implements Notificator { private final MailManager mailManager; diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java index 105cb27f0..e00db0579 100644 --- a/src/main/java/org/traccar/notificators/NotificatorPushover.java +++ b/src/main/java/org/traccar/notificators/NotificatorPushover.java @@ -24,9 +24,11 @@ import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; +@Singleton public class NotificatorPushover implements Notificator { private final NotificationFormatter notificationFormatter; diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java index 544b67a5e..e37d10888 100644 --- a/src/main/java/org/traccar/notificators/NotificatorSms.java +++ b/src/main/java/org/traccar/notificators/NotificatorSms.java @@ -25,7 +25,9 @@ import org.traccar.notification.NotificationFormatter; import org.traccar.sms.SmsManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class NotificatorSms implements Notificator { private final SmsManager smsManager; diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java index a00cd36f1..38e87c222 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java +++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java @@ -25,9 +25,11 @@ import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; +@Singleton public class NotificatorTelegram implements Notificator { private final NotificationFormatter notificationFormatter; diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 123b16ad8..9ae39f975 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -24,9 +24,11 @@ import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; import javax.inject.Inject; +import javax.inject.Singleton; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; +@Singleton public class NotificatorTraccar implements Notificator { private final NotificationFormatter notificationFormatter; diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java index f495042a5..deabeade1 100644 --- a/src/main/java/org/traccar/notificators/NotificatorWeb.java +++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java @@ -16,7 +16,6 @@ */ package org.traccar.notificators; -import org.traccar.broadcast.BroadcastService; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; @@ -24,19 +23,18 @@ import org.traccar.notification.NotificationFormatter; import org.traccar.session.ConnectionManager; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public final class NotificatorWeb implements Notificator { private final ConnectionManager connectionManager; - private final BroadcastService broadcastService; private final NotificationFormatter notificationFormatter; @Inject public NotificatorWeb( - ConnectionManager connectionManager, BroadcastService broadcastService, - NotificationFormatter notificationFormatter) { + ConnectionManager connectionManager, NotificationFormatter notificationFormatter) { this.connectionManager = connectionManager; - this.broadcastService = broadcastService; this.notificationFormatter = notificationFormatter; } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 57ed4d148..1de774dab 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -52,6 +52,7 @@ import org.traccar.storage.query.Request; import javax.annotation.Nullable; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -67,6 +68,7 @@ import java.util.Locale; import java.util.Objects; import java.util.stream.Collectors; +@Singleton public class ReportUtils { private final Config config; diff --git a/src/main/java/org/traccar/reports/common/TripsConfig.java b/src/main/java/org/traccar/reports/common/TripsConfig.java index c28cbeed4..52db97b74 100644 --- a/src/main/java/org/traccar/reports/common/TripsConfig.java +++ b/src/main/java/org/traccar/reports/common/TripsConfig.java @@ -20,7 +20,9 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class TripsConfig { @Inject diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 62ac338eb..a7ac4d6b2 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -52,7 +52,6 @@ import org.traccar.api.security.SecurityRequestFilter; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; import javax.servlet.DispatcherType; import javax.servlet.ServletException; import javax.servlet.SessionCookieConfig; @@ -76,7 +75,6 @@ public class WebServer implements LifecycleObject { private final Config config; private final Server server; - @Inject public WebServer(Injector injector, Config config) { this.injector = injector; this.config = config; -- cgit v1.2.3 From 79b3c9dd2a5ad82010ebabcd9a15bd52a1a2b765 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 08:46:10 -0700 Subject: Remove duplicate class --- .../java/org/traccar/api/ObjectMapperProvider.java | 37 ---------------------- src/main/java/org/traccar/web/WebServer.java | 4 +-- 2 files changed, 2 insertions(+), 39 deletions(-) delete mode 100644 src/main/java/org/traccar/api/ObjectMapperProvider.java diff --git a/src/main/java/org/traccar/api/ObjectMapperProvider.java b/src/main/java/org/traccar/api/ObjectMapperProvider.java deleted file mode 100644 index d63a4b9b0..000000000 --- a/src/main/java/org/traccar/api/ObjectMapperProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2015 - 2022 Anton Tananaev (anton@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.api; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import javax.inject.Inject; -import javax.ws.rs.ext.ContextResolver; - -public class ObjectMapperProvider implements ContextResolver { - - private final ObjectMapper objectMapper; - - @Inject - public ObjectMapperProvider(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - } - - @Override - public ObjectMapper getContext(Class type) { - return objectMapper; - } - -} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index a7ac4d6b2..79d19cc9b 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -45,12 +45,12 @@ import org.slf4j.LoggerFactory; import org.traccar.LifecycleObject; import org.traccar.api.CorsResponseFilter; import org.traccar.api.DateParameterConverterProvider; -import org.traccar.api.ObjectMapperProvider; import org.traccar.api.ResourceErrorHandler; import org.traccar.api.resource.ServerResource; import org.traccar.api.security.SecurityRequestFilter; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.helper.ObjectMapperContextResolver; import javax.servlet.DispatcherType; import javax.servlet.ServletException; @@ -178,7 +178,7 @@ public class WebServer implements LifecycleObject { ResourceConfig resourceConfig = new ResourceConfig(); resourceConfig.registerClasses( JacksonFeature.class, - ObjectMapperProvider.class, + ObjectMapperContextResolver.class, DateParameterConverterProvider.class, SecurityRequestFilter.class, CorsResponseFilter.class, -- cgit v1.2.3 From 4723fae87b7a6e55df2e233aa1d75bb074b294bf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 10:26:38 -0700 Subject: Update gradle version --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 00e33edef..ae04661ee 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -- cgit v1.2.3 From 8ecdbf4450d081a1e18d15d9f61d12fa2a99fe7a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 10:31:57 -0700 Subject: Update protobuf version --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 5f7396dba..82c7debe2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id "java" id "checkstyle" - id "com.google.protobuf" version "0.8.18" + id "com.google.protobuf" version "0.8.19" id "org.kordamp.gradle.project-enforcer" version "0.9.0" } @@ -14,7 +14,7 @@ ext { jettyVersion = "10.0.7" // jetty 11 javax to jakarta jerseyVersion = "2.36" // jersey 3 javax to jakarta jacksonVersion = "2.13.3" // same version as jersey-media-json-jackson dependency - protobufVersion = "3.19.3" + protobufVersion = "3.21.7" } sourceCompatibility = "11" -- cgit v1.2.3 From f7c662f04af49e29f992ab8b4c9ea24d768a32d8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 10:34:31 -0700 Subject: Update gradle plugins --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 82c7debe2..a9d97a825 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id "java" id "checkstyle" id "com.google.protobuf" version "0.8.19" - id "org.kordamp.gradle.project-enforcer" version "0.9.0" + id "org.kordamp.gradle.project-enforcer" version "0.10.0" } repositories { @@ -22,7 +22,7 @@ compileJava.options.encoding = "UTF-8" jar.destinationDirectory = file("$projectDir/target") checkstyle { - toolVersion = "9.2.1" + toolVersion = "10.3.4" configFile = "gradle/checkstyle.xml" as File checkstyleTest.enabled = false } -- cgit v1.2.3 From b06dd882bf7b8e2067240d5957315499836138c8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 11:15:46 -0700 Subject: Update Java dependencies --- build.gradle | 40 ++++++++++++------------ src/main/java/org/traccar/helper/BufferUtil.java | 18 +++++------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/build.gradle b/build.gradle index a9d97a825..6dcf6871a 100644 --- a/build.gradle +++ b/build.gradle @@ -10,10 +10,10 @@ repositories { } ext { - guiceVersion = "5.0.1" - jettyVersion = "10.0.7" // jetty 11 javax to jakarta - jerseyVersion = "2.36" // jersey 3 javax to jakarta - jacksonVersion = "2.13.3" // same version as jersey-media-json-jackson dependency + guiceVersion = "5.1.0" + jettyVersion = "10.0.12" // jetty 11 javax to jakarta + jerseyVersion = "2.37" // jersey 3 javax to jakarta + jacksonVersion = "2.13.4" // same version as jersey-media-json-jackson dependency protobufVersion = "3.21.7" } @@ -41,13 +41,13 @@ enforce { dependencies { implementation "commons-codec:commons-codec:1.15" - implementation "com.h2database:h2:2.0.206" - implementation "mysql:mysql-connector-java:8.0.27" - implementation "org.postgresql:postgresql:42.3.1" - implementation "com.microsoft.sqlserver:mssql-jdbc:9.4.1.jre11" + implementation "com.h2database:h2:2.1.214" + implementation "mysql:mysql-connector-java:8.0.30" + implementation "org.postgresql:postgresql:42.5.0" + implementation "com.microsoft.sqlserver:mssql-jdbc:11.2.1.jre11" implementation "com.zaxxer:HikariCP:5.0.1" - implementation "io.netty:netty-all:4.1.66.Final" - implementation "org.slf4j:slf4j-jdk14:2.0.0-alpha6" + implementation "io.netty:netty-all:4.1.82.Final" + implementation "org.slf4j:slf4j-jdk14:2.0.3" implementation "com.google.inject:guice:$guiceVersion" implementation "com.google.inject.extensions:guice-servlet:$guiceVersion" implementation "org.owasp.encoder:encoder:1.2.3" @@ -65,29 +65,29 @@ dependencies { implementation "org.glassfish.hk2:guice-bridge:2.6.1" // same version as jersey-hk2 implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" - implementation "org.liquibase:liquibase-core:4.7.0" + implementation "org.liquibase:liquibase-core:4.16.1" implementation "com.sun.mail:javax.mail:1.6.2" implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) implementation "org.jxls:jxls-poi:1.0.16" // needs upgrade (wait for jexl 4) - implementation "org.apache.velocity:velocity:1.7" - implementation "org.apache.velocity:velocity-tools:2.0" + implementation "org.apache.velocity:velocity:1.7" // needs upgrade + implementation "org.apache.velocity:velocity-tools:2.0" // needs upgrade implementation "org.apache.commons:commons-collections4:4.4" - implementation "org.mnode.ical4j:ical4j:3.1.2" + implementation "org.mnode.ical4j:ical4j:3.2.5" implementation "org.locationtech.spatial4j:spatial4j:0.8" - implementation "org.locationtech.jts:jts-core:1.18.2" - implementation "net.java.dev.jna:jna-platform:5.10.0" + implementation "org.locationtech.jts:jts-core:1.19.0" + implementation "net.java.dev.jna:jna-platform:5.12.1" implementation "com.github.jnr:jnr-posix:3.1.15" implementation "com.google.protobuf:protobuf-java:$protobufVersion" implementation "javax.xml.bind:jaxb-api:2.3.1" - implementation "com.sun.xml.bind:jaxb-core:3.0.2" - implementation "com.sun.xml.bind:jaxb-impl:3.0.2" + implementation "com.sun.xml.bind:jaxb-core:3.0.2" // needs upgrade + implementation "com.sun.xml.bind:jaxb-impl:3.0.2" // needs upgrade implementation "javax.activation:activation:1.1.1" - implementation "com.amazonaws:aws-java-sdk-sns:1.12.141" + implementation "com.amazonaws:aws-java-sdk-sns:1.12.314" implementation ("com.google.firebase:firebase-admin:9.0.0") { exclude group: 'com.google.cloud', module: 'google-cloud-firestore' } testImplementation "junit:junit:4.13.2" - testImplementation "org.mockito:mockito-core:3.+" + testImplementation "org.mockito:mockito-core:4.+" } task copyDependencies(type: Copy) { diff --git a/src/main/java/org/traccar/helper/BufferUtil.java b/src/main/java/org/traccar/helper/BufferUtil.java index 0dbe0a4ad..d1025f548 100644 --- a/src/main/java/org/traccar/helper/BufferUtil.java +++ b/src/main/java/org/traccar/helper/BufferUtil.java @@ -59,16 +59,16 @@ public final class BufferUtil { } public static int indexOf(ByteBuf needle, ByteBuf haystack, int startIndex, int endIndex) { - ByteBuf wrappedHaystack; - if (startIndex == haystack.readerIndex() && endIndex == haystack.writerIndex()) { - wrappedHaystack = haystack; - } else { - wrappedHaystack = Unpooled.wrappedBuffer(haystack); - wrappedHaystack.readerIndex(startIndex - haystack.readerIndex()); - wrappedHaystack.writerIndex(endIndex - haystack.readerIndex()); + int originalReaderIndex = haystack.readerIndex(); + int originalWriterIndex = haystack.writerIndex(); + try { + haystack.readerIndex(startIndex); + haystack.writerIndex(endIndex); + return ByteBufUtil.indexOf(needle, haystack); + } finally { + haystack.readerIndex(originalReaderIndex); + haystack.writerIndex(originalWriterIndex); } - int result = ByteBufUtil.indexOf(needle, wrappedHaystack); - return result < 0 ? result : startIndex + result; } } -- cgit v1.2.3 From 35fa03ecfbe0f2cc221665cba2538cf2dd155b34 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 11:36:08 -0700 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 6dcf6871a..0e7d77bce 100644 --- a/build.gradle +++ b/build.gradle @@ -100,7 +100,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.3", + "Implementation-Version": "5.4", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 3e946e672..66d2bd401 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.3 +AppVersion=5.4 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index acdc1053a..825e0d003 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.3", + "version": "5.4", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From 0cbd1277407977690c678d5a5e92ca6353dc608a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 12:41:47 -0700 Subject: Add integration tests --- tools/test-integration.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/test-integration.py b/tools/test-integration.py index 454585440..34f81ee83 100755 --- a/tools/test-integration.py +++ b/tools/test-integration.py @@ -114,6 +114,11 @@ messages = { 's168': 'S168#123456789012345#0f12#0077#LOCA:G;CELL:1,1cc,2,2795,1435,64;GDATA:A,12,160412154800,22.564025,113.242329,5.5,152,900;ALERT:0000;STATUS:89,98;WAY:0$', 'dingtek': '800001011e0692001a00000000016e008027c40000112345678901234581', 'portman': '$PTMLA,123456789012345,A,200612153351,N2543.0681W10009.2974,0,190,NA,C9830000,NA,108,8,2.66,16,GNA\r\n', + 'futureway': '410000003F2000020,IMEI:123456789012345,battery level:6,network type:7,CSQ:236F42410000009BA00004GPS:V,200902093333,0.000000N,0.000000E,0.000,0.000\r\nWIFI:3,1|90-67-1C-F7-21-6C|52&2|80-89-17-C6-79-A0|54&3|40-F4-20-EF-DD-2A|58\r\nLBS:460,0,46475066,69\r\n6A42', + 'net': '@L03612345678901234512271020161807037078881037233751000000010F850036980A4000!', + 'mobilogix': '[2020-10-25 20:45:09,T9,1,V1.2.3,123456789012,59,10.50,701,-25.236860,-45.708530,0,314]', + 'swiftech': '@@123456789012345,,0,102040,1023.9670,N,07606.8160,E,2.26,151220,A,0127,1,1,03962,00000,#', + 'ennfu': 'Ennfu:123456789012345,041504.00,A,3154.86654,N,11849.08737,E,0.053,,080121,20,3.72,21.4,V0.01$', } baseUrl = 'http://localhost:8082' -- cgit v1.2.3 From b05471157c2471d0bc053fdaa7f465602d446f4e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 17:32:30 -0700 Subject: Update submodule commit --- traccar-web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traccar-web b/traccar-web index 980956695..033c88d5d 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit 980956695258be1ff464923c76c1c6db1df397c1 +Subproject commit 033c88d5d4092f9daca90a3ef984deacd593a29e -- cgit v1.2.3 From 1a8766d8d7a6635d90d11a80935cde256d8a6dbb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 2 Oct 2022 19:14:54 -0700 Subject: Use IP as id for NMEA --- src/main/java/org/traccar/protocol/T55ProtocolDecoder.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 1529aae29..90382439e 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -28,6 +28,7 @@ import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; +import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.channels.DatagramChannel; import java.util.Date; @@ -378,6 +379,9 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { } deviceSession = getDeviceSession(channel, remoteAddress, id); sentence = sentence.substring(index); + } else if (remoteAddress instanceof InetSocketAddress) { + String host = ((InetSocketAddress) remoteAddress).getHostString(); + deviceSession = getDeviceSession(channel, remoteAddress, host); } else { deviceSession = getDeviceSession(channel, remoteAddress); } -- cgit v1.2.3 From 503f46939b8d1ac2d7f3955f3f50e314d400f006 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Oct 2022 17:23:08 -0700 Subject: Disable query logging --- debug.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug.xml b/debug.xml index e02c1b15d..66481ab52 100644 --- a/debug.xml +++ b/debug.xml @@ -13,7 +13,7 @@ ./target/media true - true + false true -- cgit v1.2.3 From 471de2a758b063cc8d6dd5321cbc459c70b88fd8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Oct 2022 17:32:10 -0700 Subject: Safer cache request --- src/main/java/org/traccar/session/cache/CacheManager.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 64397b368..ed67ed70e 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -48,6 +48,7 @@ import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -102,7 +103,11 @@ public class CacheManager implements BroadcastInterface { try { lock.readLock().lock(); return deviceLinks.get(deviceId).get(clazz).stream() - .map(id -> deviceCache.get(new CacheKey(clazz, id)).getValue()) + .map(id -> { + var cacheValue = deviceCache.get(new CacheKey(clazz, id)); + return cacheValue != null ? cacheValue.getValue() : null; + }) + .filter(Objects::nonNull) .collect(Collectors.toList()); } finally { lock.readLock().unlock(); -- cgit v1.2.3 From bcd0d17008c2c3e3ccede34a618feac53b199d02 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 4 Oct 2022 18:53:33 -0700 Subject: Concox Vl502 IMEI device id --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 15 +++++++++++++-- .../org/traccar/protocol/HuabaoProtocolDecoderTest.java | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 0639b9dcf..0eded4b42 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -160,6 +160,17 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return dateBuilder.getDate(); } + private String decodeId(ByteBuf id) { + String serial = ByteBufUtil.hexDump(id); + if (serial.matches("[0-9]+")) { + return serial; + } else { + long imei = id.readUnsignedShort(); + imei = (imei << 32) + id.readUnsignedInt(); + return String.valueOf(imei); + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -193,7 +204,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { index = buf.readUnsignedShort(); } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(id)); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, decodeId(id)); if (deviceSession == null) { return null; } @@ -208,7 +219,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { ByteBuf response = Unpooled.buffer(); response.writeShort(index); response.writeByte(RESULT_SUCCESS); - response.writeBytes(ByteBufUtil.hexDump(id).getBytes(StandardCharsets.US_ASCII)); + response.writeBytes(decodeId(id).getBytes(StandardCharsets.US_ASCII)); channel.writeAndFlush(new NetworkMessage( formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress)); } diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 3661a0202..f7873ef08 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new HuabaoProtocolDecoder(null)); + verifyNull(decoder, binary( + "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyAttribute(decoder, binary( "7e0200005e01229130231209e300000000000c002300d264a305ff322300160000000022091514493503020000a70400000000ac0400000000e5020003e62c01bc5729009ca319bbff0002dd34020754fe1a83393c03bc572900ce371a6133d704dd34020751551d00fefb9a7e"), Position.PREFIX_TEMP + 4, 29.0); -- cgit v1.2.3 From 205ed7965ae97ee6cf14deb8ec4dc94cdae75dfe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 5 Oct 2022 07:11:19 -0700 Subject: Support RFTRACK commands --- src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java index 540c3ce0b..b3ebbbf9a 100644 --- a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java @@ -23,6 +23,7 @@ import io.netty.handler.codec.http.QueryStringDecoder; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.Protocol; import org.traccar.model.CellTower; +import org.traccar.model.Command; import org.traccar.model.Network; import org.traccar.model.Position; import org.traccar.session.DeviceSession; @@ -108,7 +109,11 @@ public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { position.setNetwork(network); } - sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer("{}", StandardCharsets.UTF_8)); + String response = "{}"; + for (Command command : getCommandsManager().readQueuedCommands(position.getDeviceId(), 1)) { + response = command.getString(Command.KEY_DATA); + } + sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer(response, StandardCharsets.UTF_8)); return position; } -- cgit v1.2.3 From 525fb440430343a73a8ed402677fa24c01262372 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 5 Oct 2022 07:25:59 -0700 Subject: Additional RFTRACK data --- .../traccar/protocol/RfTrackProtocolDecoder.java | 36 +++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java index b3ebbbf9a..be9b23e37 100644 --- a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java @@ -73,7 +73,29 @@ public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { position.setDeviceTime(new Date(Long.parseLong(value))); break; case "bat": - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(value) & 0xff); + int battery = Integer.parseInt(value); + position.set(Position.KEY_BATTERY_LEVEL, battery & 0xff); + position.set("plugStatus", (battery >> 8) & 0x0f); + position.set(Position.KEY_CHARGE, ((battery >> 12) & 0x0f) == 1); + break; + case "id": + position.set("braceletId", value); + break; + case "rc": + int braceletCode = Integer.parseInt(value); + position.set("braceletCode", braceletCode & 0xffff); + position.set("braceletStatus", braceletCode >> 16); + break; + case "idt": + long braceletTime = Long.parseLong(value); + position.set("lastHeartbeat", (braceletTime >> 45) * 10); + position.set("lastPaired", ((braceletTime >> 30) & 0xffff) * 10); + position.set("lastUnpaired", ((braceletTime >> 15) & 0xffff) * 10); + break; + case "mt": + int vibrationTime = Integer.parseInt(value); + position.set("vibrationDevice", (vibrationTime & 0x7fff) * 10); + position.set("vibrationBracelet", (vibrationTime >> 15) * 10); break; case "gps": JsonObject location = Json.createReader(new StringReader(value)).readObject(); @@ -95,6 +117,18 @@ public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { mcc, mnc, cell.getInt("l"), cell.getInt("c"), cell.getInt("b"))); } break; + case "dbm": + position.set(Position.KEY_RSSI, Integer.parseInt(value)); + break; + case "bar": + position.set("pressure", Double.parseDouble(value)); + break; + case "cob": + position.set("pressureChanges", value); + break; + case "u_ids": + position.set("unpairedIds", value); + break; default: break; } -- cgit v1.2.3 From 2e0cdf2cec9be08392be2ae8826e14bc757db186 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 5 Oct 2022 08:45:12 -0700 Subject: Fix commands linked to group --- src/main/java/org/traccar/api/resource/CommandResource.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 636b45023..92804e725 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -27,6 +27,7 @@ import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.Typed; +import org.traccar.model.User; import org.traccar.model.UserRestrictions; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -82,7 +83,15 @@ public class CommandResource extends ExtendedObjectResource { public Collection get(@QueryParam("deviceId") long deviceId) throws StorageException { permissionsService.checkPermission(Device.class, getUserId(), deviceId); BaseProtocol protocol = getDeviceProtocol(deviceId); - return get(false, 0, 0, deviceId).stream().filter(command -> { + + var commands = storage.getObjects(Command.class, new Request( + new Columns.All(), + Condition.merge(List.of( + new Condition.Permission(User.class, getUserId(), Command.class), + new Condition.Permission(Device.class, deviceId, baseClass) + )))); + + return commands.stream().filter(command -> { String type = command.getType(); if (protocol != null) { return command.getTextChannel() && protocol.getSupportedTextCommands().contains(type) -- cgit v1.2.3 From bb78e15201e88fba4c71bb08d98d0f0bc5acecbf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 5 Oct 2022 08:52:25 -0700 Subject: Decode RFTRACK WiFi info --- src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java | 9 +++++++++ .../java/org/traccar/protocol/RfTrackProtocolDecoderTest.java | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java index be9b23e37..28a3ac29c 100644 --- a/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RfTrackProtocolDecoder.java @@ -26,6 +26,7 @@ import org.traccar.model.CellTower; import org.traccar.model.Command; import org.traccar.model.Network; import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; import org.traccar.session.DeviceSession; import javax.json.Json; @@ -126,6 +127,14 @@ public class RfTrackProtocolDecoder extends BaseHttpProtocolDecoder { case "cob": position.set("pressureChanges", value); break; + case "wifi": + JsonArray wifiInfo = Json.createReader(new StringReader(value)).readArray(); + for (int i = 0; i < wifiInfo.size(); i++) { + JsonObject wifi = wifiInfo.getJsonObject(i); + network.addWifiAccessPoint(WifiAccessPoint.from( + wifi.getString("m").replace('-', ':'), wifi.getInt("l"))); + } + break; case "u_ids": position.set("unpairedIds", value); break; diff --git a/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java index 19a654fa6..df19f01c6 100644 --- a/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/RfTrackProtocolDecoderTest.java @@ -12,7 +12,7 @@ public class RfTrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new RfTrackProtocolDecoder(null)); verifyPosition(decoder, request(HttpMethod.POST, "/deviceDataUpload.do", - buffer("gsm={\"n\":0,\"b\":[{\"l\":6166,\"b\":19,\"c\":21423},{\"l\":6166,\"b\":18,\"c\":21416},{\"l\":6166,\"b\":17,\"c\":21383},{\"l\":6166,\"b\":13,\"c\":21422},{\"l\":6166,\"b\":13,\"c\":21435},{\"l\":6169,\"b\":11,\"c\":21311}],\"c\":460}&wifi=[{\"l\":-49,\"t\":\"lianqin20\"}]&mt=1073709094&i=358477047125172&gps={\"a\":30.0,\"y\":31.251563,\"s\":4,\"t\":1589764496654,\"z\":0.0,\"x\":121.360346}&dbm=-53&td=1589720501123&rc=0&bar=1001.85065&u_ids=[8441644.1,53036.1]&t=1589764500713&bat=12380&v=T2.142.2_2.0_R03&i_ids=[4247328.1,53036.1,10522408.1]&idt=140736414711817&id=39163"))); + buffer("gsm={\"n\":0,\"b\":[{\"l\":6166,\"b\":19,\"c\":21423},{\"l\":6166,\"b\":18,\"c\":21416},{\"l\":6166,\"b\":17,\"c\":21383},{\"l\":6166,\"b\":13,\"c\":21422},{\"l\":6166,\"b\":13,\"c\":21435},{\"l\":6169,\"b\":11,\"c\":21311}],\"c\":460}&wifi=[{\"l\":-49,\"t\":\"lianqin20\",\"m\":\"30-B4-9E-DD-F8-2D\"}]&mt=1073709094&i=358477047125172&gps={\"a\":30.0,\"y\":31.251563,\"s\":4,\"t\":1589764496654,\"z\":0.0,\"x\":121.360346}&dbm=-53&td=1589720501123&rc=0&bar=1001.85065&u_ids=[8441644.1,53036.1]&t=1589764500713&bat=12380&v=T2.142.2_2.0_R03&i_ids=[4247328.1,53036.1,10522408.1]&idt=140736414711817&id=39163"))); } -- cgit v1.2.3 From 75f1bed91c1669e1442c2ab9ea9af0b5754db4db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 6 Oct 2022 06:42:12 -0700 Subject: Fix TAT100 cell decoding --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 8 ++++---- .../java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 4671a1088..89af20b22 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -347,10 +347,10 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (position.hasAttribute(mncKey) && position.hasAttribute(lacKey) && position.hasAttribute(cidKey)) { CellTower cellTower = CellTower.from( getConfig().getInteger(Keys.GEOLOCATION_MCC), - (Integer) position.getAttributes().remove(mncKey), - (Integer) position.getAttributes().remove(lacKey), - (Integer) position.getAttributes().remove(cidKey)); - cellTower.setSignalStrength((Integer) position.getAttributes().remove(rssiKey)); + ((Number) position.getAttributes().remove(mncKey)).intValue(), + ((Number) position.getAttributes().remove(lacKey)).intValue(), + ((Number) position.getAttributes().remove(cidKey)).longValue()); + cellTower.setSignalStrength(((Number) position.getAttributes().remove(rssiKey)).intValue()); network.addCellTower(cellTower); } } diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 197391d7f..188c4b6eb 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, binary( + "00000000000000a28e0100000183ac617e3001123eb99b1e142db4000000000000000000001d000900f000005000001503004500011e1801212d01242a012722012a18001100b5000000b600000018000000cd151000431c2d011f6981012047d701226981012347d901256981012647d8012869810129e6f304b0000304b1000304b2000304b30003000100f10000639d0002000b0000000214bf12fe000e0000000029d18c95000001000051b6")); + verifyPositions(decoder, binary( "00000000000004258e0400000182a701b49301d5d90ab7ebe4aae101be003d12000000f7003d000e00f70100ef0000f00000500500150200c800004501000100001d00001400001600001700007157010701001d00b5000b00b60006004230400018000000cd223f00ce741700430f8900440000000d00010011ffe50012001f0013ffce000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333382e0100000053a6fb624588040001ba86064f0eae51c0fdaf4d3de500000182a701b82001d5d90ab7ebe4aae101be003d12000000f0003c000d00ef0000f00100500500150200c800004501000100001d00001400001600001700007152010701001d00b5000900b60006004217e50018000000cd223f00ce741700430f5c00440000000d00010011fed60012fd1d0013f1f2000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333352e353833332d303730373139362e323333332b3030302e3434362f00000182a701bc0801d5d90ab7ebe4aae101be003d12000000fc003d000e00ef0000f00100500500150200c800004501000100001d0000140000160000170000714d01070100fc01001d00b5000900b60006004217e50018000000cd223f00ce741700430f5c00440000000d00010011fed60012fd1d0013f1f2000f03e800190bb8001a0bb8001b0bb8001c0bb800560bb800680bb8006a0bb8006c0bb8010e0000011100000114000001170000014f0000015000000151000001520000000a00f100011d2a00c700000000001000b9addc000c0000acb600040000000001320000000001330000000001340000000001350000000001c1000000000003000b000000d14675f36000ee0000000000000000000e0000000003fd509f0005014b0000014c0000014d0000014e0000018300222d3333373333352e353833332d303730373139362e323333332b3030302e3434362f00000182a7018d8d01d5d8ffa6ebe4a0ca01be006111000000f70001000100f70500000000000000000400003a10")); -- cgit v1.2.3 From ab9ff21bec23723132ed8183979be22b67c1cb3c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 6 Oct 2022 07:04:31 -0700 Subject: Fix Huabao responses --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 0eded4b42..27555d46d 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -165,8 +165,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { if (serial.matches("[0-9]+")) { return serial; } else { - long imei = id.readUnsignedShort(); - imei = (imei << 32) + id.readUnsignedInt(); + long imei = id.getUnsignedShort(0); + imei = (imei << 32) + id.getUnsignedInt(2); return String.valueOf(imei); } } -- cgit v1.2.3 From dfaef4eca85a065e35c360fd6f712b2ad62f2e7a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 7 Oct 2022 06:30:03 -0700 Subject: Fix attributes test (fix #4956) --- src/main/java/org/traccar/api/resource/AttributeResource.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index fb74b9bbe..f85e90133 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -29,7 +29,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.traccar.api.ExtendedObjectResource; -import org.traccar.config.Config; import org.traccar.model.Attribute; import org.traccar.model.Device; import org.traccar.model.Position; @@ -45,7 +44,7 @@ import org.traccar.storage.query.Request; public class AttributeResource extends ExtendedObjectResource { @Inject - private Config config; + private ComputedAttributesHandler computedAttributesHandler; public AttributeResource() { super(Attribute.class); @@ -61,7 +60,7 @@ public class AttributeResource extends ExtendedObjectResource { new Columns.All(), new Condition.LatestPositions(deviceId))); - Object result = new ComputedAttributesHandler(config, null).computeAttribute(entity, position); + Object result = computedAttributesHandler.computeAttribute(entity, position); if (result != null) { switch (entity.getType()) { case "number": -- cgit v1.2.3 From c801d33f44ae346d01e19e47a3b97c8405f4d5b4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 12 Oct 2022 17:47:35 -0700 Subject: Fix G1RUS decoding --- .../org/traccar/protocol/G1rusProtocolDecoder.java | 8 ++++++-- .../org/traccar/protocol/G1rusProtocolDecoderTest.java | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/traccar/protocol/G1rusProtocolDecoderTest.java diff --git a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java index e974e446d..17cfbc1eb 100644 --- a/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/G1rusProtocolDecoder.java @@ -124,8 +124,12 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; + buf.readUnsignedByte(); // header + buf.readUnsignedByte(); // version + int type = buf.readUnsignedByte(); String imei = String.valueOf(buf.readLong()); + buf.readerIndex(buf.readerIndex() - 1); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; @@ -144,14 +148,14 @@ public class G1rusProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.to(subtype, 6) == MSG_REGULAR) { positions.add(decodeRegular(deviceSession, buf, subtype)); } else { - buf.skipBytes(length); + buf.skipBytes(length - 1); } } return positions.isEmpty() ? null : positions; } - buf.skipBytes(2); + buf.readUnsignedShort(); // checksum buf.readUnsignedByte(); // tail return null; diff --git a/src/test/java/org/traccar/protocol/G1rusProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/G1rusProtocolDecoderTest.java new file mode 100644 index 000000000..c8b4e35fe --- /dev/null +++ b/src/test/java/org/traccar/protocol/G1rusProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class G1rusProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new G1rusProtocolDecoder(null)); + + verifyPositions(decoder, binary( + "f84604000d85f5e55298004b012ad7d524003d1d0f50726f6d61205361742031303030201556312e31302656312e312e340a03120fa0142b8475a157050401846dfc060175120a29a10d02440111002100310041005107d10ef8")); + + } + +} -- cgit v1.2.3 From acedd28b8584a18022d9e2343558f9acbad1666f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Oct 2022 07:22:20 -0700 Subject: Support OBD6 status message --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 38 +++++++++++++++------- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 4 +++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index a93c11cbc..212b4245f 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -118,6 +118,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { S5, SPACE10X, STANDARD, + OBD6, } private Variant variant; @@ -346,7 +347,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private void decodeStatus(Position position, ByteBuf buf, boolean batteryLevel) { + private void decodeStatus(Position position, ByteBuf buf) { int status = buf.readUnsignedByte(); @@ -381,13 +382,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { default: break; } - - if (batteryLevel) { - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte() * 100 / 6); - } else { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - } - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); } private String decodeAlarm(short value) { @@ -793,8 +787,22 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasStatus(type)) { - decodeStatus(position, buf, true); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + decodeStatus(position, buf); + if (variant == Variant.OBD6) { + int signal = buf.readUnsignedShort(); + int satellites = BitUtil.between(signal, 10, 15) + BitUtil.between(signal, 5, 10); + position.set(Position.KEY_SATELLITES, satellites); + position.set(Position.KEY_RSSI, BitUtil.to(signal, 5)); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + buf.readUnsignedByte(); // language + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + buf.readUnsignedByte(); // working mode + position.set(Position.KEY_POWER, buf.readUnsignedShort() / 100.0); + } else { + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte() * 100 / 6); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + } } if (type == MSG_GPS_LBS_1) { @@ -823,10 +831,14 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } } else if (variant == Variant.VXT01) { - decodeStatus(position, buf, false); + decodeStatus(position, buf); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); buf.readUnsignedByte(); // alarm extension } else if (variant == Variant.S5) { - decodeStatus(position, buf, false); + decodeStatus(position, buf); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("oil", buf.readUnsignedShort()); int temperature = buf.readUnsignedByte(); @@ -1355,6 +1367,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.S5; } else if (header == 0x7878 && type == MSG_LBS_STATUS && length >= 0x17) { variant = Variant.SPACE10X; + } else if (header == 0x7878 && type == MSG_STATUS && length == 0x13) { + variant = Variant.OBD6; } else { variant = Variant.STANDARD; } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index ebda38823..d1789bb16 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "7878131302801900002e42016f000000003a0177ef180d0a"), + Position.KEY_POWER, 3.67); + verifyAttribute(decoder, binary( "78782526160913063918c002780fab0c44750f00040008027f14084c0038420600030c020007398e0d0a"), Position.KEY_ALARM, Position.ALARM_TAMPERING); -- cgit v1.2.3 From 4c8e98ed409df6e12128591eb1d8d0cf0856deb7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Oct 2022 10:31:54 -0700 Subject: Refactor database code (fix #4961) --- src/main/java/org/traccar/MainEventHandler.java | 2 +- .../java/org/traccar/api/BaseObjectResource.java | 11 +++-- src/main/java/org/traccar/api/MediaFilter.java | 2 +- .../org/traccar/api/resource/CommandResource.java | 2 +- .../org/traccar/api/resource/DeviceResource.java | 8 ++-- .../org/traccar/api/resource/EventResource.java | 2 +- .../org/traccar/api/resource/PasswordResource.java | 7 +-- .../org/traccar/api/resource/PositionResource.java | 2 +- .../org/traccar/api/resource/ServerResource.java | 2 +- .../org/traccar/api/resource/SessionResource.java | 2 +- .../org/traccar/api/resource/UserResource.java | 3 +- .../org/traccar/api/security/LoginService.java | 7 +-- .../traccar/api/security/PermissionsService.java | 4 +- .../java/org/traccar/database/CommandsManager.java | 8 ++-- .../org/traccar/database/DeviceLookupService.java | 2 +- .../java/org/traccar/handler/FilterHandler.java | 2 +- .../handler/events/GeofenceEventHandler.java | 3 +- .../traccar/handler/events/MotionEventHandler.java | 2 +- .../handler/events/OverspeedEventHandler.java | 2 +- .../org/traccar/helper/model/PositionUtil.java | 2 +- src/main/java/org/traccar/model/Device.java | 7 ++- .../org/traccar/reports/EventsReportProvider.java | 4 +- .../org/traccar/reports/GpxExportProvider.java | 2 +- .../org/traccar/reports/KmlExportProvider.java | 2 +- .../org/traccar/reports/RouteReportProvider.java | 2 +- .../org/traccar/reports/StopsReportProvider.java | 2 +- .../org/traccar/reports/TripsReportProvider.java | 2 +- .../org/traccar/reports/common/ReportUtils.java | 4 +- .../org/traccar/session/ConnectionManager.java | 4 +- .../org/traccar/session/cache/CacheManager.java | 12 ++--- .../java/org/traccar/storage/DatabaseStorage.java | 25 +++++----- .../java/org/traccar/storage/QueryBuilder.java | 54 +++++++++++----------- .../java/org/traccar/storage/query/Columns.java | 3 +- .../java/org/traccar/storage/query/Condition.java | 8 +--- 34 files changed, 102 insertions(+), 104 deletions(-) diff --git a/src/main/java/org/traccar/MainEventHandler.java b/src/main/java/org/traccar/MainEventHandler.java index 17bcad0dd..877f03ae7 100644 --- a/src/main/java/org/traccar/MainEventHandler.java +++ b/src/main/java/org/traccar/MainEventHandler.java @@ -90,7 +90,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { updatedDevice.setPositionId(position.getId()); storage.updateObject(updatedDevice, new Request( new Columns.Include("positionId"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", updatedDevice.getId()))); cacheManager.updatePosition(position); connectionManager.updatePosition(true, position); diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 0ec2bfeaa..904781e54 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -56,7 +56,7 @@ public abstract class BaseObjectResource extends BaseResour public Response getSingle(@PathParam("id") long id) throws StorageException { permissionsService.checkPermission(baseClass, getUserId(), id); T entity = storage.getObject(baseClass, new Request( - new Columns.All(), new Condition.Equals("id", "id", id))); + new Columns.All(), new Condition.Equals("id", id))); if (entity != null) { return Response.ok(entity).build(); } else { @@ -86,7 +86,7 @@ public abstract class BaseObjectResource extends BaseResour if (entity instanceof User) { User before = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); + new Columns.All(), new Condition.Equals("id", entity.getId()))); permissionsService.checkUserUpdate(getUserId(), before, (User) entity); } else if (entity instanceof Group) { Group group = (Group) entity; @@ -97,12 +97,13 @@ public abstract class BaseObjectResource extends BaseResour storage.updateObject(entity, new Request( new Columns.Exclude("id"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", entity.getId()))); if (entity instanceof User) { User user = (User) entity; if (user.getHashedPassword() != null) { storage.updateObject(entity, new Request( - new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + new Columns.Include("hashedPassword", "salt"), + new Condition.Equals("id", entity.getId()))); } } cacheManager.updateOrInvalidate(true, entity); @@ -117,7 +118,7 @@ public abstract class BaseObjectResource extends BaseResour permissionsService.checkEdit(getUserId(), baseClass, false); permissionsService.checkPermission(baseClass, getUserId(), id); - storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); + storage.removeObject(baseClass, new Request(new Condition.Equals("id", id))); cacheManager.invalidate(baseClass, id); LogAction.remove(getUserId(), baseClass, id); diff --git a/src/main/java/org/traccar/api/MediaFilter.java b/src/main/java/org/traccar/api/MediaFilter.java index 6d95c66a8..ab75bdc5d 100644 --- a/src/main/java/org/traccar/api/MediaFilter.java +++ b/src/main/java/org/traccar/api/MediaFilter.java @@ -84,7 +84,7 @@ public class MediaFilter implements Filter { String[] parts = path != null ? path.split("/") : null; if (parts != null && parts.length >= 2) { Device device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", parts[1]))); + new Columns.All(), new Condition.Equals("uniqueId", parts[1]))); if (device != null) { permissionsServiceProvider.get().checkPermission(Device.class, userId, device.getId()); chain.doFilter(request, response); diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 92804e725..80b9fd18f 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -110,7 +110,7 @@ public class CommandResource extends ExtendedObjectResource { permissionsService.checkPermission(Command.class, getUserId(), entity.getId()); long deviceId = entity.getDeviceId(); entity = storage.getObject(baseClass, new Request( - new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); + new Columns.All(), new Condition.Equals("id", entity.getId()))); entity.setDeviceId(deviceId); } else { permissionsService.checkRestriction(getUserId(), UserRestrictions::getLimitCommands); diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 1d9bc20ec..c0b0cea0d 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -84,14 +84,14 @@ public class DeviceResource extends BaseObjectResource { result.addAll(storage.getObjects(Device.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("uniqueId", "uniqueId", uniqueId), + new Condition.Equals("uniqueId", uniqueId), new Condition.Permission(User.class, getUserId(), Device.class))))); } for (Long deviceId : deviceIds) { result.addAll(storage.getObjects(Device.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("id", "id", deviceId), + new Condition.Equals("id", deviceId), new Condition.Permission(User.class, getUserId(), Device.class))))); } return result; @@ -142,7 +142,7 @@ public class DeviceResource extends BaseObjectResource { device.setPositionId(position.getId()); storage.updateObject(device, new Request( new Columns.Include("positionId"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", device.getId()))); try { cacheManager.addDevice(position.getDeviceId()); @@ -169,7 +169,7 @@ public class DeviceResource extends BaseObjectResource { Device device = storage.getObject(Device.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("id", "id", deviceId), + new Condition.Equals("id", deviceId), new Condition.Permission(User.class, getUserId(), Device.class)))); if (device != null) { String name = "device"; diff --git a/src/main/java/org/traccar/api/resource/EventResource.java b/src/main/java/org/traccar/api/resource/EventResource.java index 3870e9af9..afdaf52b5 100644 --- a/src/main/java/org/traccar/api/resource/EventResource.java +++ b/src/main/java/org/traccar/api/resource/EventResource.java @@ -41,7 +41,7 @@ public class EventResource extends BaseResource { @GET public Event get(@PathParam("id") long id) throws StorageException { Event event = storage.getObject(Event.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", id))); + new Columns.All(), new Condition.Equals("id", id))); if (event == null) { throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()); } diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index 625ff4cb1..ebf4e3b91 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -59,7 +59,7 @@ public class PasswordResource extends BaseResource { throws StorageException, MessagingException, GeneralSecurityException, IOException { User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("email", "email", email))); + new Columns.All(), new Condition.Equals("email", email))); if (user != null) { var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); velocityContext.put("token", tokenManager.generateToken(user.getId())); @@ -78,11 +78,12 @@ public class PasswordResource extends BaseResource { long userId = tokenManager.verifyToken(token); User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", userId))); + new Columns.All(), new Condition.Equals("id", userId))); if (user != null) { user.setPassword(password); storage.updateObject(user, new Request( - new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + new Columns.Include("hashedPassword", "salt"), + new Condition.Equals("id", userId))); return Response.ok().build(); } return Response.status(Response.Status.NOT_FOUND).build(); diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java index 7d7921085..042dd1e23 100644 --- a/src/main/java/org/traccar/api/resource/PositionResource.java +++ b/src/main/java/org/traccar/api/resource/PositionResource.java @@ -67,7 +67,7 @@ public class PositionResource extends BaseResource { var positions = new ArrayList(); for (long positionId : positionIds) { Position position = storage.getObject(Position.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", positionId))); + new Columns.All(), new Condition.Equals("id", positionId))); permissionsService.checkPermission(Device.class, getUserId(), position.getDeviceId()); positions.add(position); } diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index e35cd7d95..e7f0b93ca 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -76,7 +76,7 @@ public class ServerResource extends BaseResource { permissionsService.checkAdmin(getUserId()); storage.updateObject(entity, new Request( new Columns.Exclude("id"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", entity.getId()))); cacheManager.updateOrInvalidate(true, entity); LogAction.edit(getUserId(), entity); return Response.ok(entity).build(); diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 05f492d73..1e984fbd0 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -122,7 +122,7 @@ public class SessionResource extends BaseResource { public User get(@PathParam("id") long userId) throws StorageException { permissionsService.checkAdmin(getUserId()); User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", userId))); + new Columns.All(), new Condition.Equals("id", userId))); request.getSession().setAttribute(USER_ID_KEY, user.getId()); LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request)); return user; diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index dd71de4c6..91875ef51 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -100,7 +100,8 @@ public class UserResource extends BaseObjectResource { entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); storage.updateObject(entity, new Request( - new Columns.Include("hashedPassword", "salt"), new Condition.Equals("id", "id"))); + new Columns.Include("hashedPassword", "salt"), + new Condition.Equals("id", entity.getId()))); LogAction.create(getUserId(), entity); diff --git a/src/main/java/org/traccar/api/security/LoginService.java b/src/main/java/org/traccar/api/security/LoginService.java index 32487f06b..88bafcfb5 100644 --- a/src/main/java/org/traccar/api/security/LoginService.java +++ b/src/main/java/org/traccar/api/security/LoginService.java @@ -58,7 +58,7 @@ public class LoginService { } long userId = tokenManager.verifyToken(token); User user = storage.getObject(User.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", userId))); + new Columns.All(), new Condition.Equals("id", userId))); if (user != null) { checkUserEnabled(user); } @@ -66,11 +66,12 @@ public class LoginService { } public User login(String email, String password) throws StorageException { + email = email.trim(); User user = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Or( - new Condition.Equals("email", "email", email.trim()), - new Condition.Equals("login", "email")))); + new Condition.Equals("email", email), + new Condition.Equals("login", email)))); if (user != null) { if (ldapProvider != null && user.getLogin() != null && ldapProvider.login(user.getLogin(), password) || !forceLdap && user.isPasswordValid(password)) { diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index ddfaaab94..0d4877fdb 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -62,7 +62,7 @@ public class PermissionsService { user = new ServiceAccountUser(); } else { user = storage.getObject( - User.class, new Request(new Columns.All(), new Condition.Equals("id", "id", userId))); + User.class, new Request(new Columns.All(), new Condition.Equals("id", userId))); } } return user; @@ -187,7 +187,7 @@ public class PermissionsService { var object = storage.getObject(clazz, new Request( new Columns.Include("id"), new Condition.And( - new Condition.Equals("id", "id", objectId), + new Condition.Equals("id", objectId), new Condition.Permission( User.class, userId, clazz.equals(User.class) ? ManagedUser.class : clazz)))); if (object == null) { diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 53040ad53..764ea637b 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -69,9 +69,9 @@ public class CommandsManager implements BroadcastInterface { throw new RuntimeException("SMS not configured"); } Device device = storage.getObject(Device.class, new Request( - new Columns.Include("positionId", "phone"), new Condition.Equals("id", "id", deviceId))); + new Columns.Include("positionId", "phone"), new Condition.Equals("id", deviceId))); Position position = storage.getObject(Position.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getPositionId()))); + new Columns.All(), new Condition.Equals("id", device.getPositionId()))); if (position != null) { BaseProtocol protocol = serverManager.getProtocol(position.getProtocol()); protocol.sendTextCommand(device.getPhone(), command); @@ -101,12 +101,12 @@ public class CommandsManager implements BroadcastInterface { try { var commands = storage.getObjects(QueuedCommand.class, new Request( new Columns.All(), - new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Equals("deviceId", deviceId), new Order(false, "id"), new Limit(count))); for (var command : commands) { storage.removeObject(QueuedCommand.class, new Request( - new Condition.Equals("id", "id", command.getId()))); + new Condition.Equals("id", command.getId()))); } return commands.stream().map(QueuedCommand::toCommand).collect(Collectors.toList()); } catch (StorageException e) { diff --git a/src/main/java/org/traccar/database/DeviceLookupService.java b/src/main/java/org/traccar/database/DeviceLookupService.java index 9cf0899ee..28910c24a 100644 --- a/src/main/java/org/traccar/database/DeviceLookupService.java +++ b/src/main/java/org/traccar/database/DeviceLookupService.java @@ -108,7 +108,7 @@ public class DeviceLookupService { for (String uniqueId : uniqueIds) { if (!isThrottled(uniqueId)) { device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("uniqueId", "uniqueId", uniqueId))); + new Columns.All(), new Condition.Equals("uniqueId", uniqueId))); if (device != null) { lookupSucceeded(uniqueId); break; diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index f09cb16a3..3722f2a22 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -88,7 +88,7 @@ public class FilterHandler extends BaseDataHandler { return storage.getObject(Position.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Equals("deviceId", deviceId), new Condition.Compare("fixTime", "<=", "time", date)), new Order(true, "fixTime"), new Limit(1))); diff --git a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java index b1be7e8ad..9414f4b31 100644 --- a/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/GeofenceEventHandler.java @@ -82,7 +82,8 @@ public class GeofenceEventHandler extends BaseEventHandler { try { storage.updateObject(device, new Request( - new Columns.Include("geofenceIds"), new Condition.Equals("id", "id"))); + new Columns.Include("geofenceIds"), + new Condition.Equals("id", device.getId()))); } catch (StorageException e) { throw new RuntimeException("Update device geofences error", e); } diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 3511cf682..1b9763c41 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -76,7 +76,7 @@ public class MotionEventHandler extends BaseEventHandler { try { storage.updateObject(device, new Request( new Columns.Include("motionState", "motionTime", "motionDistance"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", device.getId()))); } catch (StorageException e) { LOGGER.warn("Update device motion error", e); } diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java index 3928fcc88..4d6aa8857 100644 --- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java +++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java @@ -113,7 +113,7 @@ public class OverspeedEventHandler extends BaseEventHandler { try { storage.updateObject(device, new Request( new Columns.Include("overspeedState", "overspeedTime", "overspeedGeofenceId"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", device.getId()))); } catch (StorageException e) { LOGGER.warn("Update device overspeed error", e); } diff --git a/src/main/java/org/traccar/helper/model/PositionUtil.java b/src/main/java/org/traccar/helper/model/PositionUtil.java index 31f828947..6c380b81a 100644 --- a/src/main/java/org/traccar/helper/model/PositionUtil.java +++ b/src/main/java/org/traccar/helper/model/PositionUtil.java @@ -59,7 +59,7 @@ public final class PositionUtil { return storage.getObjects(Position.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Equals("deviceId", deviceId), new Condition.Between("fixTime", "from", from, "to", to)), new Order("fixTime"))); } diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 147b0fd20..7728172cb 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -52,22 +52,22 @@ public class Device extends GroupedModel implements Disableable { private String status; + @QueryIgnore public String getStatus() { return status != null ? status : STATUS_OFFLINE; } - @QueryIgnore public void setStatus(String status) { this.status = status != null ? status.trim() : null; } private Date lastUpdate; + @QueryIgnore public Date getLastUpdate() { return this.lastUpdate; } - @QueryIgnore public void setLastUpdate(Date lastUpdate) { this.lastUpdate = lastUpdate; } @@ -79,18 +79,17 @@ public class Device extends GroupedModel implements Disableable { return positionId; } - @QueryIgnore public void setPositionId(long positionId) { this.positionId = positionId; } private List geofenceIds; + @QueryIgnore public List getGeofenceIds() { return geofenceIds; } - @QueryIgnore public void setGeofenceIds(List geofenceIds) { if (geofenceIds != null) { this.geofenceIds = geofenceIds.stream().map(Number::longValue).collect(Collectors.toList()); diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 878c0265d..d0d4fe8bf 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -64,7 +64,7 @@ public class EventsReportProvider { return storage.getObjects(Event.class, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("deviceId", "deviceId", deviceId), + new Condition.Equals("deviceId", deviceId), new Condition.Between("eventTime", "from", from, "to", to)), new Order("eventTime"))); } @@ -134,7 +134,7 @@ public class EventsReportProvider { sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() > 0) { Group group = storage.getObject(Group.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); + new Columns.All(), new Condition.Equals("id", device.getGroupId()))); if (group != null) { deviceEvents.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/GpxExportProvider.java b/src/main/java/org/traccar/reports/GpxExportProvider.java index f1a0f292d..ccbd97fc3 100644 --- a/src/main/java/org/traccar/reports/GpxExportProvider.java +++ b/src/main/java/org/traccar/reports/GpxExportProvider.java @@ -42,7 +42,7 @@ public class GpxExportProvider { OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { var device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId))); + new Columns.All(), new Condition.Equals("id", deviceId))); var positions = PositionUtil.getPositions(storage, deviceId, from, to); try (PrintWriter writer = new PrintWriter(outputStream)) { diff --git a/src/main/java/org/traccar/reports/KmlExportProvider.java b/src/main/java/org/traccar/reports/KmlExportProvider.java index e8b5c4278..24fcfb8ab 100644 --- a/src/main/java/org/traccar/reports/KmlExportProvider.java +++ b/src/main/java/org/traccar/reports/KmlExportProvider.java @@ -43,7 +43,7 @@ public class KmlExportProvider { OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException { var device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId))); + new Columns.All(), new Condition.Equals("id", deviceId))); var positions = PositionUtil.getPositions(storage, deviceId, from, to); var dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index 0f618822e..3ee651619 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -80,7 +80,7 @@ public class RouteReportProvider { sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() > 0) { Group group = storage.getObject(Group.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); + new Columns.All(), new Condition.Equals("id", device.getGroupId()))); if (group != null) { deviceRoutes.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index ba61ef6a1..ec3fd2215 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -87,7 +87,7 @@ public class StopsReportProvider { sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() > 0) { Group group = storage.getObject(Group.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); + new Columns.All(), new Condition.Equals("id", device.getGroupId()))); if (group != null) { deviceStops.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index 2d9bcdfbf..265811354 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -87,7 +87,7 @@ public class TripsReportProvider { sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() > 0) { Group group = storage.getObject(Group.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); + new Columns.All(), new Condition.Equals("id", device.getGroupId()))); if (group != null) { deviceTrips.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 1de774dab..120dadcf5 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -95,7 +95,7 @@ public class ReportUtils { return storage.getObject(clazz, new Request( new Columns.All(), new Condition.And( - new Condition.Equals("id", "id", objectId), + new Condition.Equals("id", objectId), new Condition.Permission(User.class, userId, clazz)))); } @@ -166,7 +166,7 @@ public class ReportUtils { if (driverUniqueId != null) { Driver driver = storage.getObject(Driver.class, new Request( new Columns.All(), - new Condition.Equals("uniqueId", "uniqueId", driverUniqueId))); + new Condition.Equals("uniqueId", driverUniqueId))); if (driver != null) { return driver.getName(); } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 9e50c9ead..37a42d827 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -215,7 +215,7 @@ public class ConnectionManager implements BroadcastInterface { if (device == null) { try { device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId))); + new Columns.All(), new Condition.Equals("id", deviceId))); } catch (StorageException e) { LOGGER.warn("Failed to get device", e); } @@ -265,7 +265,7 @@ public class ConnectionManager implements BroadcastInterface { try { storage.updateObject(device, new Request( new Columns.Include("status", "lastUpdate"), - new Condition.Equals("id", "id"))); + new Condition.Equals("id", deviceId))); } catch (StorageException e) { LOGGER.warn("Update device status error", e); } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index ed67ed70e..8f2e7ba93 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -201,7 +201,7 @@ public class CacheManager implements BroadcastInterface { public void invalidateObject(boolean local, Class clazz, long id) { try { var object = storage.getObject(clazz, new Request( - new Columns.All(), new Condition.Equals("id", "id", id))); + new Columns.All(), new Condition.Equals("id", id))); if (object != null) { updateOrInvalidate(local, object); } else { @@ -286,7 +286,7 @@ public class CacheManager implements BroadcastInterface { Map, Set> links = new HashMap<>(); Device device = storage.getObject(Device.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", deviceId))); + new Columns.All(), new Condition.Equals("id", deviceId))); if (device != null) { addObject(deviceId, device); @@ -294,7 +294,7 @@ public class CacheManager implements BroadcastInterface { long groupId = device.getGroupId(); while (groupDepth < GROUP_DEPTH_LIMIT && groupId > 0) { Group group = storage.getObject(Group.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", groupId))); + new Columns.All(), new Condition.Equals("id", groupId))); links.computeIfAbsent(Group.class, k -> new LinkedHashSet<>()).add(group.getId()); addObject(deviceId, group); groupId = group.getGroupId(); @@ -311,7 +311,7 @@ public class CacheManager implements BroadcastInterface { var scheduled = (ScheduledModel) object; if (scheduled.getCalendarId() > 0) { var calendar = storage.getObject(Calendar.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", scheduled.getCalendarId()))); + new Columns.All(), new Condition.Equals("id", scheduled.getCalendarId()))); links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) .add(calendar.getId()); addObject(deviceId, calendar); @@ -336,7 +336,7 @@ public class CacheManager implements BroadcastInterface { addObject(deviceId, notification); if (notification.getCalendarId() > 0) { var calendar = storage.getObject(Calendar.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", notification.getCalendarId()))); + new Columns.All(), new Condition.Equals("id", notification.getCalendarId()))); links.computeIfAbsent(Notification.class, k -> new LinkedHashSet<>()) .add(calendar.getId()); addObject(deviceId, calendar); @@ -348,7 +348,7 @@ public class CacheManager implements BroadcastInterface { if (device.getPositionId() > 0) { devicePositions.put(deviceId, storage.getObject(Position.class, new Request( - new Columns.All(), new Condition.Equals("id", "id", device.getPositionId())))); + new Columns.All(), new Condition.Equals("id", device.getPositionId())))); } } } diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 8ca464147..884c8fca8 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -57,7 +57,7 @@ public class DatabaseStorage extends Storage { if (request.getColumns() instanceof Columns.All) { query.append('*'); } else { - query.append(formatColumns(request.getColumns(), clazz, "get", c -> c)); + query.append(formatColumns(request.getColumns().getColumns(clazz, "set"), c -> c)); } query.append(" FROM ").append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); @@ -76,16 +76,17 @@ public class DatabaseStorage extends Storage { @Override public long addObject(T entity, Request request) throws StorageException { + List columns = request.getColumns().getColumns(entity.getClass(), "get"); StringBuilder query = new StringBuilder("INSERT INTO "); query.append(getStorageName(entity.getClass())); query.append("("); - query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c)); + query.append(formatColumns(columns, c -> c)); query.append(") VALUES ("); - query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> ':' + c)); + query.append(formatColumns(columns, c -> ':' + c)); query.append(")"); try { QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString(), true); - builder.setObject(entity); + builder.setObject(entity, columns); return builder.executeUpdate(); } catch (SQLException e) { throw new StorageException(e); @@ -94,14 +95,15 @@ public class DatabaseStorage extends Storage { @Override public void updateObject(T entity, Request request) throws StorageException { + List columns = request.getColumns().getColumns(entity.getClass(), "get"); StringBuilder query = new StringBuilder("UPDATE "); query.append(getStorageName(entity.getClass())); query.append(" SET "); - query.append(formatColumns(request.getColumns(), entity.getClass(), "set", c -> c + " = :" + c)); + query.append(formatColumns(columns, c -> c + " = :" + c)); query.append(formatCondition(request.getCondition())); try { QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); - builder.setObject(entity); + builder.setObject(entity, columns); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { builder.setValue(variable.getKey(), variable.getValue()); } @@ -135,12 +137,10 @@ public class DatabaseStorage extends Storage { query.append(Permission.getStorageName(ownerClass, propertyClass)); var conditions = new LinkedList(); if (ownerId > 0) { - conditions.add(new Condition.Equals( - Permission.getKey(ownerClass), Permission.getKey(ownerClass), ownerId)); + conditions.add(new Condition.Equals(Permission.getKey(ownerClass), ownerId)); } if (propertyId > 0) { - conditions.add(new Condition.Equals( - Permission.getKey(propertyClass), Permission.getKey(propertyClass), propertyId)); + conditions.add(new Condition.Equals(Permission.getKey(propertyClass), propertyId)); } Condition combinedCondition = Condition.merge(conditions); query.append(formatCondition(combinedCondition)); @@ -230,9 +230,8 @@ public class DatabaseStorage extends Storage { return results; } - private String formatColumns( - Columns columns, Class clazz, String type, Function mapper) { - return columns.getColumns(clazz, type).stream().map(mapper).collect(Collectors.joining(", ")); + private String formatColumns(List columns, Function mapper) { + return columns.stream().map(mapper).collect(Collectors.joining(", ")); } private String formatCondition(Condition genericCondition) throws StorageException { diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index a58ebe2b4..fa71a8e8f 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -37,10 +37,12 @@ import java.sql.Timestamp; import java.sql.Types; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; @SuppressWarnings("UnusedReturnValue") public final class QueryBuilder { @@ -283,36 +285,32 @@ public final class QueryBuilder { return this; } - public QueryBuilder setObject(Object object) throws SQLException { - - Method[] methods = object.getClass().getMethods(); - - for (Method method : methods) { - if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 - && !method.getName().equals("getClass")) { - String name = method.getName().substring(3); - try { - if (method.getReturnType().equals(boolean.class)) { - setBoolean(name, (Boolean) method.invoke(object)); - } else if (method.getReturnType().equals(int.class)) { - setInteger(name, (Integer) method.invoke(object)); - } else if (method.getReturnType().equals(long.class)) { - setLong(name, (Long) method.invoke(object), name.endsWith("Id")); - } else if (method.getReturnType().equals(double.class)) { - setDouble(name, (Double) method.invoke(object)); - } else if (method.getReturnType().equals(String.class)) { - setString(name, (String) method.invoke(object)); - } else if (method.getReturnType().equals(Date.class)) { - setDate(name, (Date) method.invoke(object)); - } else if (method.getReturnType().equals(byte[].class)) { - setBlob(name, (byte[]) method.invoke(object)); - } else { - setString(name, objectMapper.writeValueAsString(method.invoke(object))); - } - } catch (IllegalAccessException | InvocationTargetException | JsonProcessingException error) { - LOGGER.warn("Get property error", error); + public QueryBuilder setObject(Object object, List columns) throws SQLException { + + try { + for (String column : columns) { + Method method = object.getClass().getMethod( + "get" + Character.toUpperCase(column.charAt(0)) + column.substring(1)); + if (method.getReturnType().equals(boolean.class)) { + setBoolean(column, (Boolean) method.invoke(object)); + } else if (method.getReturnType().equals(int.class)) { + setInteger(column, (Integer) method.invoke(object)); + } else if (method.getReturnType().equals(long.class)) { + setLong(column, (Long) method.invoke(object), column.endsWith("Id")); + } else if (method.getReturnType().equals(double.class)) { + setDouble(column, (Double) method.invoke(object)); + } else if (method.getReturnType().equals(String.class)) { + setString(column, (String) method.invoke(object)); + } else if (method.getReturnType().equals(Date.class)) { + setDate(column, (Date) method.invoke(object)); + } else if (method.getReturnType().equals(byte[].class)) { + setBlob(column, (byte[]) method.invoke(object)); + } else { + setString(column, objectMapper.writeValueAsString(method.invoke(object))); } } + } catch (ReflectiveOperationException | JsonProcessingException e) { + LOGGER.warn("Set object error", e); } return this; diff --git a/src/main/java/org/traccar/storage/query/Columns.java b/src/main/java/org/traccar/storage/query/Columns.java index 545995b3c..a00400b36 100644 --- a/src/main/java/org/traccar/storage/query/Columns.java +++ b/src/main/java/org/traccar/storage/query/Columns.java @@ -17,6 +17,7 @@ package org.traccar.storage.query; import org.traccar.storage.QueryIgnore; +import java.beans.Introspector; import java.lang.reflect.Method; import java.util.Arrays; import java.util.LinkedList; @@ -36,7 +37,7 @@ public abstract class Columns { if (method.getName().startsWith(type) && method.getParameterTypes().length == parameterCount && !method.isAnnotationPresent(QueryIgnore.class) && !method.getName().equals("getClass")) { - columns.add(method.getName().substring(3).toLowerCase()); + columns.add(Introspector.decapitalize(method.getName().substring(3))); } } return columns; diff --git a/src/main/java/org/traccar/storage/query/Condition.java b/src/main/java/org/traccar/storage/query/Condition.java index 136b0402b..08b199052 100644 --- a/src/main/java/org/traccar/storage/query/Condition.java +++ b/src/main/java/org/traccar/storage/query/Condition.java @@ -34,12 +34,8 @@ public interface Condition { } class Equals extends Compare { - public Equals(String column, String variable) { - this(column, variable, null); - } - - public Equals(String column, String variable, Object value) { - super(column, "=", variable, value); + public Equals(String column, Object value) { + super(column, "=", column, value); } } -- cgit v1.2.3 From 47579ba635ad87af13f9626923e0168ff53e5178 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Oct 2022 10:35:02 -0700 Subject: Fix lint issues --- src/main/java/org/traccar/storage/QueryBuilder.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index fa71a8e8f..2f4c07406 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -37,12 +37,10 @@ import java.sql.Timestamp; import java.sql.Types; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Set; @SuppressWarnings("UnusedReturnValue") public final class QueryBuilder { -- cgit v1.2.3 From 85cef19d557b3aa0e306c3efe0bdcf8020042775 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 14 Oct 2022 06:29:45 -0700 Subject: MiniFinder Rex bark alarm --- .../java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 8 ++++++-- .../java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 228578571..bec05ffc2 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -50,7 +50,7 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_SERVICES = 0x03; public static final int MSG_RESPONSE = 0x7F; - private String decodeAlarm(int code) { + private String decodeAlarm(long code) { if (BitUtil.check(code, 0)) { return Position.ALARM_LOW_BATTERY; } @@ -181,7 +181,11 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); break; case 0x02: - position.set(Position.KEY_ALARM, decodeAlarm(buf.readIntLE())); + long alarm = buf.readUnsignedIntLE(); + position.set(Position.KEY_ALARM, decodeAlarm(alarm)); + if (BitUtil.check(alarm, 31)) { + position.set("bark", true); + } break; case 0x14: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index a6006d6a7..0809996f6 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -10,6 +10,10 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Minifinder2ProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "ab102600080f1400011001383633393231303339393833343736092429b347633003a96409020000008027b34763"), + "bark", true); + verifyPositions(decoder, binary( "AB103D0035A700000110013836373733303035333430333237390924AC5783620103C250162030CC5F0D5002FB432D00AF005A3158006D0A00000B0931EC5783620A000000")); -- cgit v1.2.3 From 3f01f92125851e325b8e3e4ef679d832fe3dee21 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Oct 2022 06:47:59 -0700 Subject: Fix MS SQL limit (fix #4958) --- .../java/org/traccar/database/CommandsManager.java | 4 +--- .../java/org/traccar/handler/FilterHandler.java | 4 +--- .../java/org/traccar/storage/DatabaseStorage.java | 28 +++++++++++++--------- src/main/java/org/traccar/storage/query/Order.java | 12 +++++++--- .../java/org/traccar/storage/query/Request.java | 6 ----- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/traccar/database/CommandsManager.java b/src/main/java/org/traccar/database/CommandsManager.java index 764ea637b..df399cd7a 100644 --- a/src/main/java/org/traccar/database/CommandsManager.java +++ b/src/main/java/org/traccar/database/CommandsManager.java @@ -31,7 +31,6 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; @@ -102,8 +101,7 @@ public class CommandsManager implements BroadcastInterface { var commands = storage.getObjects(QueuedCommand.class, new Request( new Columns.All(), new Condition.Equals("deviceId", deviceId), - new Order(false, "id"), - new Limit(count))); + new Order("id", false, count))); for (var command : commands) { storage.removeObject(QueuedCommand.class, new Request( new Condition.Equals("id", command.getId()))); diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java index 3722f2a22..994276bb6 100644 --- a/src/main/java/org/traccar/handler/FilterHandler.java +++ b/src/main/java/org/traccar/handler/FilterHandler.java @@ -30,7 +30,6 @@ import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; @@ -90,8 +89,7 @@ public class FilterHandler extends BaseDataHandler { new Condition.And( new Condition.Equals("deviceId", deviceId), new Condition.Compare("fixTime", "<=", "time", date)), - new Order(true, "fixTime"), - new Limit(1))); + new Order("fixTime", true, 1))); } private boolean filterInvalid(Position position) { diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index 884c8fca8..a049a641c 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -24,7 +24,6 @@ import org.traccar.model.GroupedModel; import org.traccar.model.Permission; import org.traccar.storage.query.Columns; import org.traccar.storage.query.Condition; -import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; @@ -43,12 +42,19 @@ public class DatabaseStorage extends Storage { private final Config config; private final DataSource dataSource; private final ObjectMapper objectMapper; + private final String databaseType; @Inject public DatabaseStorage(Config config, DataSource dataSource, ObjectMapper objectMapper) { this.config = config; this.dataSource = dataSource; this.objectMapper = objectMapper; + + try { + databaseType = dataSource.getConnection().getMetaData().getDatabaseProductName(); + } catch (SQLException e) { + throw new RuntimeException(e); + } } @Override @@ -62,7 +68,6 @@ public class DatabaseStorage extends Storage { query.append(" FROM ").append(getStorageName(clazz)); query.append(formatCondition(request.getCondition())); query.append(formatOrder(request.getOrder())); - query.append(formatLimit(request.getLimit())); try { QueryBuilder builder = QueryBuilder.create(config, dataSource, objectMapper, query.toString()); for (Map.Entry variable : getConditionVariables(request.getCondition()).entrySet()) { @@ -302,15 +307,16 @@ public class DatabaseStorage extends Storage { if (order.getDescending()) { result.append(" DESC"); } - } - return result.toString(); - } - - private String formatLimit(Limit limit) { - StringBuilder result = new StringBuilder(); - if (limit != null) { - result.append(" LIMIT "); - result.append(limit.getValue()); + if (order.getLimit() > 0) { + if (databaseType.equals("Microsoft SQL Server")) { + result.append(" OFFSET 0 ROWS FETCH FIRST "); + result.append(order.getLimit()); + result.append(" ROWS ONLY"); + } else { + result.append(" LIMIT "); + result.append(order.getLimit()); + } + } } return result.toString(); } diff --git a/src/main/java/org/traccar/storage/query/Order.java b/src/main/java/org/traccar/storage/query/Order.java index d12acc83b..b41f145e9 100644 --- a/src/main/java/org/traccar/storage/query/Order.java +++ b/src/main/java/org/traccar/storage/query/Order.java @@ -19,14 +19,16 @@ public class Order { private final String column; private final boolean descending; + private final int limit; public Order(String column) { - this(false, column); + this(column, false, 0); } - public Order(boolean descending, String column) { + public Order(String column, boolean descending, int limit) { this.column = column; - this.descending = descending; + this.descending = false; + this.limit = limit; } public String getColumn() { @@ -37,4 +39,8 @@ public class Order { return descending; } + public int getLimit() { + return limit; + } + } diff --git a/src/main/java/org/traccar/storage/query/Request.java b/src/main/java/org/traccar/storage/query/Request.java index 41aa37bf1..6e9cecc63 100644 --- a/src/main/java/org/traccar/storage/query/Request.java +++ b/src/main/java/org/traccar/storage/query/Request.java @@ -20,7 +20,6 @@ public class Request { private final Columns columns; private final Condition condition; private final Order order; - private final Limit limit; public Request(Columns columns) { this(columns, null, null); @@ -42,7 +41,6 @@ public class Request { this.columns = columns; this.condition = condition; this.order = order; - this.limit = limit; } public Columns getColumns() { @@ -57,8 +55,4 @@ public class Request { return order; } - public Limit getLimit() { - return limit; - } - } -- cgit v1.2.3 From db97378f2210818d0600420bc9c69103ddea248b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 16 Oct 2022 12:54:28 -0700 Subject: Improve Suntech support --- .../org/traccar/protocol/SuntechProtocolDecoder.java | 18 ++++++++++++++++-- .../org/traccar/protocol/SuntechProtocolEncoder.java | 10 +++++----- .../traccar/protocol/SuntechProtocolDecoderTest.java | 4 ++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index f1097abac..e67bd7a71 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -43,6 +43,7 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.TimeZone; +import java.util.stream.Collectors; public class SuntechProtocolDecoder extends BaseProtocolDecoder { @@ -203,12 +204,16 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_POWER_RESTORED; case 41: return Position.ALARM_POWER_CUT; + case 42: + return Position.ALARM_SOS; case 46: return Position.ALARM_ACCELERATION; case 47: return Position.ALARM_BRAKING; case 50: return Position.ALARM_JAMMING; + case 132: + return Position.ALARM_DOOR; default: return null; } @@ -468,7 +473,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { String type = values[index++]; - if (!type.equals("STT") && !type.equals("ALT") && !type.equals("BLE")) { + if (!type.equals("STT") && !type.equals("ALT") && !type.equals("BLE") && !type.equals("RES")) { return null; } @@ -481,6 +486,14 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_TYPE, type); + if (type.equals("RES")) { + getLastLocation(position, null); + position.set( + Position.KEY_RESULT, + Arrays.stream(values, index, values.length).collect(Collectors.joining(";"))); + return position; + } + int mask; if (type.equals("BLE")) { mask = 0b1100000110110; @@ -581,7 +594,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (type.equals("ALT")) { if (BitUtil.check(mask, 19)) { - position.set("alertId", values[index++]); + int alertId = Integer.parseInt(values[index++]); + position.set(Position.KEY_ALARM, decodeAlert(alertId)); } if (BitUtil.check(mask, 20)) { position.set("alertModifier", values[index++]); diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java index 597acaae8..53308f968 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java @@ -45,13 +45,13 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { } if (universal) { - return encodeUniversalCommand(channel, command); + return encodeUniversalCommand(command); } else { - return encodeLegacyCommand(channel, prefix, command); + return encodeLegacyCommand(prefix, command); } } - protected Object encodeUniversalCommand(Channel channel, Command command) { + protected Object encodeUniversalCommand(Command command) { switch (command.getType()) { case Command.TYPE_REBOOT_DEVICE: return formatCommand(command, "CMD;%s;03;03\r", Command.KEY_UNIQUE_ID); @@ -84,7 +84,7 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_ENGINE_STOP: return formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "CMD;%s;02;02\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ALARM_ARM: return formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); case Command.TYPE_ALARM_DISARM: @@ -94,7 +94,7 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { } } - protected Object encodeLegacyCommand(Channel channel, String prefix, Command command) { + protected Object encodeLegacyCommand(String prefix, Command command) { switch (command.getType()) { case Command.TYPE_REBOOT_DEVICE: return formatCommand(command, prefix + "CMD;%s;02;Reboot\r", Command.KEY_UNIQUE_ID); diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index 30959c8b9..ebd48c5c7 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -83,6 +83,10 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { var decoder = inject(new SuntechProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "RES;4309999001;04;02;TEST"), + Position.KEY_RESULT, "04;02;TEST"); + verifyPosition(decoder, buffer( "BLE;1140000053;114;1.0.1;20211001;17:27:09;+28.433465;-82.565891;1;-43;-46;-41;ACB89523EF68;247;0;0")); -- cgit v1.2.3 From 94bb9f2ace4134b4cfc9d0ca2a16f79ce9ec4bce Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 16 Oct 2022 16:45:29 -0700 Subject: Remove commented lines --- debug.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/debug.xml b/debug.xml index 66481ab52..7b5c1acff 100644 --- a/debug.xml +++ b/debug.xml @@ -25,8 +25,4 @@ true 6037 - - -- cgit v1.2.3 From dcecec13f6392980512e0ded566680c3dd657ab4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 17 Oct 2022 16:54:56 -0700 Subject: Fix Suntech alert decoding --- src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index e67bd7a71..047a1822a 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -856,7 +856,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } else { - String[] values = buf.toString(StandardCharsets.US_ASCII).split(";"); + String[] values = buf.toString(StandardCharsets.US_ASCII).split(";", -1); prefix = values[0]; if (prefix.equals("CRR")) { diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index ebd48c5c7..e25ad124c 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -83,6 +83,10 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { var decoder = inject(new SuntechProtocolDecoder(null)); + verifyAttribute(decoder, buffer( + "ALT;0950030205;3FFFFF;95;1.0.11;0;20221017;21:41:30;02F2F402;334;20;0F1D;45;+25.791061;-100.170745;0.00;0.00;18;1;00000101;00000000;42;2;"), + Position.KEY_ALARM, Position.ALARM_SOS); + verifyAttribute(decoder, buffer( "RES;4309999001;04;02;TEST"), Position.KEY_RESULT, "04;02;TEST"); -- cgit v1.2.3 From ab6df268d8b22b1d99c1b6ee1770a50d56b784e3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 18 Oct 2022 06:34:48 -0700 Subject: Add BCE frame tests --- .../org/traccar/protocol/BceFrameDecoderTest.java | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/java/org/traccar/protocol/BceFrameDecoderTest.java diff --git a/src/test/java/org/traccar/protocol/BceFrameDecoderTest.java b/src/test/java/org/traccar/protocol/BceFrameDecoderTest.java new file mode 100644 index 000000000..e5a442f2f --- /dev/null +++ b/src/test/java/org/traccar/protocol/BceFrameDecoderTest.java @@ -0,0 +1,26 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class BceFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new BceFrameDecoder()); + + verifyNull( + decoder.decode(null, null, binary("23424345230d0a"))); + + verifyFrame( + binary("18ed450cf31403001501a5050a66207bde6442534451380a66207bde6440534451380a66207bde6414534451380a66207bde6416534451380a96207bde6415534451386247277bde03c0ffffc081400069f934418ce94b42001c88ee0000000000908c060103025d19ab004b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b5c40000000000000001010000000aa6277bde008f5344513862b7277bde03c0ffffc081400051f8344185e94b420c1c85fa0000000000d18c060103025d19ab00470000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b5c40000000000000001010400000ab6277bde009153445138a0"), + decoder.decode(null, null, binary("18ed450cf31403001501a5050a66207bde6442534451380a66207bde6440534451380a66207bde6414534451380a66207bde6416534451380a96207bde6415534451386247277bde03c0ffffc081400069f934418ce94b42001c88ee0000000000908c060103025d19ab004b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b5c40000000000000001010000000aa6277bde008f5344513862b7277bde03c0ffffc081400051f8344185e94b420c1c85fa0000000000d18c060103025d19ab00470000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b5c40000000000000001010400000ab6277bde009153445138a0"))); + + verifyFrame( + binary("18ed450cf31403000200a5070e"), + decoder.decode(null, null, binary("18ed450cf31403000200a5070e"))); + + } + +} -- cgit v1.2.3 From ca504df5720f1b26830f9f5f4099d1e9903ea2f1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 18 Oct 2022 06:38:53 -0700 Subject: Add BCE test case --- src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java index 4117833c0..89ab64cd3 100644 --- a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class BceProtocolDecoderTest extends ProtocolTest { var decoder = inject(new BceProtocolDecoder(null)); + verifyPositions(decoder, binary( + "18ed450cf3140300c800a53a62972f7bde03c0ffffc0814000e03e354135e34b42121c55fb0000000000d18c060103025d19ab00540000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b5c400000000000000010104080162a72f7bde03c0ffffc0814000ef3e8e4431e34b42061c54fc0000000000d18c060103025d19ab00540000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b5c400000000000000010100000053")); + verifyNull(decoder, binary( "3ab90b71bc1503000300c10bff11")); -- cgit v1.2.3 From 8f537de3bbf4dc1a742222dfd3123090b79e6419 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Oct 2022 09:24:25 -0700 Subject: Fix command queue issue --- schema/changelog-5.5.xml | 15 +++++++++++++++ schema/changelog-master.xml | 1 + src/main/java/org/traccar/model/BaseCommand.java | 10 ---------- src/main/java/org/traccar/model/Command.java | 10 ++++++++++ src/main/java/org/traccar/model/QueuedCommand.java | 5 +++-- 5 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 schema/changelog-5.5.xml diff --git a/schema/changelog-5.5.xml b/schema/changelog-5.5.xml new file mode 100644 index 000000000..4f5b210c5 --- /dev/null +++ b/schema/changelog-5.5.xml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index e877c1afd..cc39c5c41 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -35,5 +35,6 @@ + diff --git a/src/main/java/org/traccar/model/BaseCommand.java b/src/main/java/org/traccar/model/BaseCommand.java index 16df9c126..f87b8ef65 100644 --- a/src/main/java/org/traccar/model/BaseCommand.java +++ b/src/main/java/org/traccar/model/BaseCommand.java @@ -17,16 +17,6 @@ package org.traccar.model; public class BaseCommand extends Message { - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - private boolean textChannel; public boolean getTextChannel() { diff --git a/src/main/java/org/traccar/model/Command.java b/src/main/java/org/traccar/model/Command.java index 4ea619e95..99988dd82 100644 --- a/src/main/java/org/traccar/model/Command.java +++ b/src/main/java/org/traccar/model/Command.java @@ -96,4 +96,14 @@ public class Command extends BaseCommand { super.setDeviceId(deviceId); } + private String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + } diff --git a/src/main/java/org/traccar/model/QueuedCommand.java b/src/main/java/org/traccar/model/QueuedCommand.java index fff77a22b..96a1eca4b 100644 --- a/src/main/java/org/traccar/model/QueuedCommand.java +++ b/src/main/java/org/traccar/model/QueuedCommand.java @@ -15,18 +15,19 @@ */ package org.traccar.model; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.traccar.storage.StorageName; import java.util.HashMap; @StorageName("tc_commands_queue") +@JsonIgnoreProperties(ignoreUnknown = true) public class QueuedCommand extends BaseCommand { public static QueuedCommand fromCommand(Command command) { QueuedCommand queuedCommand = new QueuedCommand(); queuedCommand.setDeviceId(command.getDeviceId()); queuedCommand.setType(command.getType()); - queuedCommand.setDescription(command.getDescription()); queuedCommand.setTextChannel(command.getTextChannel()); queuedCommand.setAttributes(new HashMap<>(command.getAttributes())); return queuedCommand; @@ -36,7 +37,7 @@ public class QueuedCommand extends BaseCommand { Command command = new Command(); command.setDeviceId(getDeviceId()); command.setType(getType()); - command.setDescription(getDescription()); + command.setDescription(""); command.setTextChannel(getTextChannel()); command.setAttributes(new HashMap<>(getAttributes())); return command; -- cgit v1.2.3 From 73b174094effa2a2c9c3a076b5c244ba832a90c2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Oct 2022 05:54:29 -0700 Subject: Add Minifinder HDOP --- src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index bec05ffc2..f0ae28756 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -198,7 +198,9 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); position.setCourse(buf.readUnsignedShortLE()); position.setAltitude(buf.readShortLE()); - position.setValid(buf.readUnsignedShortLE() > 0); + int hdop = buf.readUnsignedShortLE(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop * 0.1); position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; -- cgit v1.2.3 From eef6c34d403fa5bf2ca0ae757792633c36052769 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Oct 2022 13:28:20 -0700 Subject: Update GPS103 command (fix #4964) --- src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java index e662e9b04..9a899eeeb 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java @@ -49,7 +49,7 @@ public class Gps103ProtocolEncoder extends StringProtocolEncoder implements Stri case Command.TYPE_CUSTOM: return formatCommand(command, "**,imei:%s,%s", Command.KEY_UNIQUE_ID, Command.KEY_DATA); case Command.TYPE_POSITION_STOP: - return formatCommand(command, "**,imei:%s,A", Command.KEY_UNIQUE_ID); + return formatCommand(command, "**,imei:%s,D", Command.KEY_UNIQUE_ID); case Command.TYPE_POSITION_SINGLE: return formatCommand(command, "**,imei:%s,B", Command.KEY_UNIQUE_ID); case Command.TYPE_POSITION_PERIODIC: -- cgit v1.2.3 From 8fe9e3f6ce857705fa609aa2728f73fdf98f3dbb Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Tue, 25 Oct 2022 11:06:27 +0800 Subject: Huabao Protocol: Add CC888 heartbeat packet From CC888 protocol When vehicle engine is OFF, the device will stop uploading location information to platform server, it will send heart beat message to platform server every 2 minutes, the heart beat message ID is 0x0506, the message body of heart beat message is empty. The platform will reply device with general replay message ID 0x8001 --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 27555d46d..cbaa6b9fd 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -51,6 +51,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GENERAL_RESPONSE = 0x8001; public static final int MSG_GENERAL_RESPONSE_2 = 0x4401; public static final int MSG_HEARTBEAT = 0x0002; + public static final int MSG_HEARTBEAT_2 = 0x0506; public static final int MSG_TERMINAL_REGISTER = 0x0100; public static final int MSG_TERMINAL_REGISTER_RESPONSE = 0x8100; public static final int MSG_TERMINAL_CONTROL = 0x8105; @@ -224,7 +225,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress)); } - } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_PHOTO) { + } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_PHOTO || type == MSG_HEARTBEAT_2) { sendGeneralResponse(channel, remoteAddress, id, type, index); -- cgit v1.2.3 From fcdec06d0a6b9a742709de967b122ad6213637c1 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Wed, 26 Oct 2022 09:02:53 +0800 Subject: Huabao: code style - ordering Co-authored-by: Anton Tananaev --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index cbaa6b9fd..b6940aecf 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -225,7 +225,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, false, response), remoteAddress)); } - } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_PHOTO || type == MSG_HEARTBEAT_2) { + } else if (type == MSG_TERMINAL_AUTH || type == MSG_HEARTBEAT || type == MSG_HEARTBEAT_2 || type == MSG_PHOTO) { sendGeneralResponse(channel, remoteAddress, id, type, index); -- cgit v1.2.3 From 8ceb20c2d9c70f5e0aa107095a23c187019401f1 Mon Sep 17 00:00:00 2001 From: jcardus Date: Wed, 26 Oct 2022 14:48:31 +0100 Subject: 2 Bugs on maintenance According to the documentation: "Traccar can help control maintenance intervals of devices. There are two attributes to configure: maintenance.start and maintenance.interval. They can be set in device, group or server attributes. Traccar generates event every time totalDistance attribute gets over maintenance.start + maintenance.interval * N value where N is a natural number. Example: maintenance.start=6000000, maintenance.interval=8000000 Events will be generated when totalDistance goes over 6000 km, 14000 km, 22000 km and so on." In this example, the event won't be fired when it goes over 6000 km. If maintenance.interval < maintenance.start and maintenance.start is multiple of maintenance.interval then the event will be fired before maintenance.start because the comparison will be on negative numbers. Another solution would be to use absolute numbers on the comparison. Example: maintenance.start = 10 000 000 maintenance.interval = 2 000 000 the event will be fired when it goes over 2 000 000 the event wont' be fired when it goes over 10 000 000 --- .../traccar/handler/events/MaintenanceEventHandler.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 4fcfcd079..25a622373 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -51,13 +51,15 @@ public class MaintenanceEventHandler extends BaseEventHandler { if (maintenance.getPeriod() != 0) { double oldValue = lastPosition.getDouble(maintenance.getType()); double newValue = position.getDouble(maintenance.getType()); - if (oldValue != 0.0 && newValue != 0.0 - && (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod()) + if (oldValue != 0.0 && newValue != 0.0 && newValue >= maintenance.getStart()) { + if (oldValue < maintenance.getStart() + || (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod()) < (long) ((newValue - maintenance.getStart()) / maintenance.getPeriod())) { - Event event = new Event(Event.TYPE_MAINTENANCE, position); - event.setMaintenanceId(maintenance.getId()); - event.set(maintenance.getType(), newValue); - events.put(event, position); + Event event = new Event(Event.TYPE_MAINTENANCE, position); + event.setMaintenanceId(maintenance.getId()); + event.set(maintenance.getType(), newValue); + events.put(event, position); + } } } } -- cgit v1.2.3 From 3c7afdf75c4f3d045c0d51355d6ce62622eb2c4d Mon Sep 17 00:00:00 2001 From: jcardus Date: Wed, 26 Oct 2022 15:02:22 +0100 Subject: Update MaintenanceEventHandler.java trailing spaces --- src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 25a622373..909950acf 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -52,7 +52,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { double oldValue = lastPosition.getDouble(maintenance.getType()); double newValue = position.getDouble(maintenance.getType()); if (oldValue != 0.0 && newValue != 0.0 && newValue >= maintenance.getStart()) { - if (oldValue < maintenance.getStart() + if (oldValue < maintenance.getStart() || (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod()) < (long) ((newValue - maintenance.getStart()) / maintenance.getPeriod())) { Event event = new Event(Event.TYPE_MAINTENANCE, position); -- cgit v1.2.3 From 907e5d1669c154e266383a275c1212baea1bda2a Mon Sep 17 00:00:00 2001 From: jcardus Date: Wed, 26 Oct 2022 17:11:14 +0100 Subject: added MaintenanceEventHandlerTest --- .../events/MaintenanceEventHandlerTest.java | 60 ++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/java/org/traccar/handler/events/MaintenanceEventHandlerTest.java diff --git a/src/test/java/org/traccar/handler/events/MaintenanceEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MaintenanceEventHandlerTest.java new file mode 100644 index 000000000..aa2d0bbe3 --- /dev/null +++ b/src/test/java/org/traccar/handler/events/MaintenanceEventHandlerTest.java @@ -0,0 +1,60 @@ +package org.traccar.handler.events; + +import org.junit.Test; +import org.traccar.BaseTest; +import org.traccar.model.Maintenance; +import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; + +import java.util.Arrays; +import java.util.Date; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.anyLong; + +public class MaintenanceEventHandlerTest extends BaseTest { + + @Test + public void testMaintenanceEventHandler() { + Position lastPosition = new Position(); + lastPosition.setDeviceId(1); + lastPosition.setFixTime(new Date(0)); + + Position position = new Position(); + position.setDeviceId(1); + position.setFixTime(new Date(0)); + + var maintenance = mock(Maintenance.class); + when(maintenance.getType()).thenReturn(Position.KEY_TOTAL_DISTANCE); + var maintenances = Arrays.asList(maintenance); + + var cacheManager = mock(CacheManager.class); + when(cacheManager.getDeviceObjects(anyLong(), eq(Maintenance.class))).thenReturn(maintenances); + when(cacheManager.getPosition(anyLong())).thenReturn(lastPosition); + MaintenanceEventHandler eventHandler = new MaintenanceEventHandler(cacheManager); + + when(maintenance.getStart()).thenReturn(10000.0); + when(maintenance.getPeriod()).thenReturn(2000.0); + + lastPosition.set(Position.KEY_TOTAL_DISTANCE, 1999); + position.set(Position.KEY_TOTAL_DISTANCE, 2001); + assertTrue(eventHandler.analyzePosition(position).isEmpty()); + + lastPosition.set(Position.KEY_TOTAL_DISTANCE, 3999); + position.set(Position.KEY_TOTAL_DISTANCE, 4001); + assertTrue(eventHandler.analyzePosition(position).isEmpty()); + + lastPosition.set(Position.KEY_TOTAL_DISTANCE, 9999); + position.set(Position.KEY_TOTAL_DISTANCE, 10001); + assertTrue(eventHandler.analyzePosition(position).size() == 1); + + lastPosition.set(Position.KEY_TOTAL_DISTANCE, 11999); + position.set(Position.KEY_TOTAL_DISTANCE, 12001); + assertTrue(eventHandler.analyzePosition(position).size() == 1); + + } + +} -- cgit v1.2.3 From cf59eb2c734f7d8bd5ea8f9ff82d4dc91492693f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 26 Oct 2022 21:51:15 -0700 Subject: Remove duplicate token --- src/main/java/org/traccar/api/resource/PasswordResource.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/traccar/api/resource/PasswordResource.java b/src/main/java/org/traccar/api/resource/PasswordResource.java index ebf4e3b91..2d87a8665 100644 --- a/src/main/java/org/traccar/api/resource/PasswordResource.java +++ b/src/main/java/org/traccar/api/resource/PasswordResource.java @@ -62,7 +62,6 @@ public class PasswordResource extends BaseResource { new Columns.All(), new Condition.Equals("email", email))); if (user != null) { var velocityContext = textTemplateFormatter.prepareContext(permissionsService.getServer(), user); - velocityContext.put("token", tokenManager.generateToken(user.getId())); var fullMessage = textTemplateFormatter.formatMessage(velocityContext, "passwordReset", "full"); mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody()); } -- cgit v1.2.3 From ab10e710a9c57ef761ea9955198273db5f473581 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 27 Oct 2022 07:17:25 -0700 Subject: Fix DT700 temperature decoding --- .../java/org/traccar/protocol/HuabaoProtocolDecoder.java | 15 +++++++++------ .../org/traccar/protocol/HuabaoProtocolDecoderTest.java | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index b6940aecf..27a5094a0 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -408,6 +408,13 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } } + private double decodeCustomDouble(ByteBuf buf) { + int b1 = buf.readByte(); + int b2 = buf.readUnsignedByte(); + int sign = b1 != 0 ? b1 / Math.abs(b1) : 1; + return sign * (Math.abs(b1) + b2 / 255.0); + } + private Position decodeLocation(DeviceSession deviceSession, ByteBuf buf) { Position position = new Position(getProtocolName()); @@ -529,12 +536,8 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { while (buf.readerIndex() < endIndex) { int sensorIndex = buf.readUnsignedByte(); buf.skipBytes(6); // mac - position.set( - Position.PREFIX_TEMP + sensorIndex, - buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); - position.set( - "humidity" + sensorIndex, - buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01); + position.set(Position.PREFIX_TEMP + sensorIndex, decodeCustomDouble(buf)); + position.set("humidity" + sensorIndex, decodeCustomDouble(buf)); } break; case 0xEB: diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index f7873ef08..9bbd375dc 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -15,8 +15,8 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); verifyAttribute(decoder, binary( - "7e0200005e01229130231209e300000000000c002300d264a305ff322300160000000022091514493503020000a70400000000ac0400000000e5020003e62c01bc5729009ca319bbff0002dd34020754fe1a83393c03bc572900ce371a6133d704dd34020751551d00fefb9a7e"), - Position.PREFIX_TEMP + 4, 29.0); + "7e02000042012291302260198f00000000800c012300d2651605ff3188001e0000000022102510310003020000a70400000000ac040000012ce5020003e60b03bc572900ce2eef183200e7030000005c7e"), + Position.PREFIX_TEMP + 3, -17.094117647058823); verifyAttribute(decoder, binary( "7E0200008201215233475100030000000000000003015A7F6106CF8CEC003D0000000021071311481901040000005630011931011AE10200755D3D0601CC0024990A7dA0032301CC002499099B2941FC01CC002499099B29430B01CC0024990A7dA0290601CC0024990A7dA015FD01CC0026220994506BFFFE157C010400000001F10C000000000000000000000000997E"), -- cgit v1.2.3 From c59ba066b1437e98af10a413b9e0c29f0e443b26 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 27 Oct 2022 17:56:32 -0700 Subject: Support Teltonika DualCam video --- .../traccar/protocol/DualcamProtocolDecoder.java | 36 ++++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index c5835bc7d..e646c4e4a 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,8 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { private String uniqueId; private int packetCount; private int currentPacket; - private ByteBuf photo; + private boolean video; + private ByteBuf media; @Override protected Object decode( @@ -64,9 +65,22 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { long settings = buf.readUnsignedInt(); if (channel != null && deviceSession != null) { ByteBuf response = Unpooled.buffer(); - if (BitUtil.between(settings, 26, 28) > 0) { + if (BitUtil.between(settings, 26, 30) > 0) { response.writeShort(MSG_FILE_REQUEST); - String file = BitUtil.check(settings, 26) ? "%photof" : "%photor"; + String file; + if (BitUtil.check(settings, 26)) { + video = false; + file = "%photof"; + } else if (BitUtil.check(settings, 27)) { + video = false; + file = "%photor"; + } else if (BitUtil.check(settings, 28)) { + video = true; + file = "%videof"; + } else { + video = true; + file = "%videor"; + } response.writeShort(file.length()); response.writeCharSequence(file, StandardCharsets.US_ASCII); } else { @@ -79,7 +93,7 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // length packetCount = buf.readInt(); currentPacket = 1; - photo = Unpooled.buffer(); + media = Unpooled.buffer(); if (channel != null) { ByteBuf response = Unpooled.buffer(); response.writeShort(MSG_RESUME); @@ -90,17 +104,21 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { break; case MSG_DATA: buf.readUnsignedShort(); // length - photo.writeBytes(buf, buf.readableBytes() - 2); + media.writeBytes(buf, buf.readableBytes() - 2); if (currentPacket == packetCount) { deviceSession = getDeviceSession(channel, remoteAddress); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); try { - position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, photo, "jpg")); + if (video) { + position.set(Position.KEY_VIDEO, writeMediaFile(uniqueId, media, "h265")); + } else { + position.set(Position.KEY_IMAGE, writeMediaFile(uniqueId, media, "jpg")); + } } finally { - photo.release(); - photo = null; + media.release(); + media = null; } if (channel != null) { ByteBuf response = Unpooled.buffer(); -- cgit v1.2.3 From 0508411fc388d8a7495b43378cfa6265a24c02d2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 28 Oct 2022 05:05:18 -0700 Subject: Missing iStartek parameters --- .../java/org/traccar/protocol/StartekProtocolDecoder.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index b2fcd5452..8e3624cb5 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -83,9 +83,9 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .groupBegin() .number("(d+)?|") // rpm .number("(d+)?|") // engine load - .number("d*|") // maf flow - .number("d*|") // intake pressure - .number("d*|") // intake temperature + .number("(d+)?|") // maf flow + .number("(d+)?|") // intake pressure + .number("(d+)?|") // intake temperature .number("(d+)?|") // throttle .number("(d+)?|") // coolant temperature .number("(d+)?|") // instant fuel @@ -224,6 +224,11 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext(6)) { position.set(Position.KEY_RPM, parser.nextInt()); position.set(Position.KEY_ENGINE_LOAD, parser.nextInt()); + position.set("airFlow", parser.nextInt()); + position.set("airPressure", parser.nextInt()); + if (parser.hasNext()) { + position.set("airTemp", parser.nextInt() - 40); + } position.set(Position.KEY_THROTTLE, parser.nextInt()); if (parser.hasNext()) { position.set(Position.KEY_COOLANT_TEMP, parser.nextInt() - 40); -- cgit v1.2.3 From 87d54329d8d6ba14f37e15967079bcfc7299228c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 28 Oct 2022 06:08:10 -0700 Subject: Address in events report (fix #4761) --- .../org/traccar/reports/EventsReportProvider.java | 11 +++++++++++ templates/export/events.xlsx | Bin 8763 -> 9023 bytes 2 files changed, 11 insertions(+) diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index d0d4fe8bf..30f55ba80 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -24,6 +24,7 @@ import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Group; import org.traccar.model.Maintenance; +import org.traccar.model.Position; import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.Storage; @@ -102,6 +103,7 @@ public class EventsReportProvider { ArrayList sheetNames = new ArrayList<>(); HashMap geofenceNames = new HashMap<>(); HashMap maintenanceNames = new HashMap<>(); + HashMap positions = new HashMap<>(); for (Device device: reportUtils.getAccessibleDevices(userId, deviceIds, groupIds)) { Collection events = getEvents(device.getId(), from, to); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); @@ -129,6 +131,14 @@ public class EventsReportProvider { iterator.remove(); } } + for (Event event : events) { + long positionId = event.getPositionId(); + if (positionId > 0) { + Position position = storage.getObject(Position.class, new Request( + new Columns.All(), new Condition.Equals("id", positionId))); + positions.put(positionId, position); + } + } DeviceReportSection deviceEvents = new DeviceReportSection(); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); @@ -150,6 +160,7 @@ public class EventsReportProvider { context.putVar("sheetNames", sheetNames); context.putVar("geofenceNames", geofenceNames); context.putVar("maintenanceNames", maintenanceNames); + context.putVar("positions", positions); context.putVar("from", from); context.putVar("to", to); reportUtils.processTemplateWithSheets(inputStream, outputStream, context); diff --git a/templates/export/events.xlsx b/templates/export/events.xlsx index a6366750c..d0120ab8e 100644 Binary files a/templates/export/events.xlsx and b/templates/export/events.xlsx differ -- cgit v1.2.3 From d5ac6aa371b5dfd9a6613e693a6afc711fb740df Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 1 Nov 2022 17:06:51 -0700 Subject: Improve permission check --- src/main/java/org/traccar/api/security/PermissionsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 0d4877fdb..71acb3d48 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -104,7 +104,7 @@ public class PermissionsService { } else if (clazz.equals(Device.class)) { denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly() || addition && getUser(userId).getDeviceLimit() == 0; - if (addition && getUser(userId).getDeviceLimit() > 0) { + if (!denied && addition && getUser(userId).getDeviceLimit() > 0) { int deviceCount = storage.getObjects(Device.class, new Request( new Columns.Include("id"), new Condition.Permission(User.class, userId, Device.class))).size(); -- cgit v1.2.3 From 49646eccd5ec57013c78ea0a0776c206f812cb0b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 1 Nov 2022 21:26:02 -0700 Subject: Better Meiligao commands --- .../org/traccar/protocol/MeiligaoProtocol.java | 1 + .../traccar/protocol/MeiligaoProtocolEncoder.java | 47 +++++++++++++++++----- .../protocol/MeiligaoProtocolEncoderTest.java | 4 ++ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java index 2c853f0e1..492094ce3 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java @@ -30,6 +30,7 @@ public class MeiligaoProtocol extends BaseProtocol { setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, + Command.TYPE_OUTPUT_CONTROL, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_GEOFENCE, diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java index 21f9f8801..03f0e7ecf 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -24,8 +24,10 @@ import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; +import org.traccar.model.Device; import java.nio.charset.StandardCharsets; +import java.util.Set; import java.util.TimeZone; public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { @@ -57,15 +59,36 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { return buf; } - @Override - protected Object encodeCommand(Command command) { + private ByteBuf encodeOutputCommand(long deviceId, int index, int value) { + + int outputCount; + int outputType; + + String model = getCacheManager().getObject(Device.class, deviceId).getModel(); - boolean alternative = AttributeUtil.lookup( - getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); + if (model != null && Set.of("TK510", "GT08", "TK208", "TK228", "MT05").contains(model)) { + outputCount = 5; + outputType = MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1; + } else { + outputCount = 1; + boolean alternative = AttributeUtil.lookup( + getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), deviceId); + outputType = alternative + ? MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1 + : MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_2; + } + + ByteBuf content = Unpooled.buffer(); - int outputControlMessageType = alternative - ? MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_1 - : MeiligaoProtocolDecoder.MSG_OUTPUT_CONTROL_2; + for (int i = 1; i <= outputCount; i++) { + content.writeByte(i == index ? value : 2); + } + + return encodeContent(deviceId, outputType, content); + } + + @Override + protected Object encodeCommand(Command command) { ByteBuf content = Unpooled.buffer(); @@ -75,12 +98,14 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { case Command.TYPE_POSITION_PERIODIC: content.writeShort(command.getInteger(Command.KEY_FREQUENCY) / 10); return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_TRACK_BY_INTERVAL, content); + case Command.TYPE_OUTPUT_CONTROL: + int index = Integer.parseInt(command.getString(Command.KEY_INDEX)) - 1; + int value = Integer.parseInt(command.getString(Command.KEY_DATA)); + return encodeOutputCommand(command.getDeviceId(), index, value); case Command.TYPE_ENGINE_STOP: - content.writeByte(0x01); - return encodeContent(command.getDeviceId(), outputControlMessageType, content); + return encodeOutputCommand(command.getDeviceId(), 1, 1); case Command.TYPE_ENGINE_RESUME: - content.writeByte(0x00); - return encodeContent(command.getDeviceId(), outputControlMessageType, content); + return encodeOutputCommand(command.getDeviceId(), 1, 0); case Command.TYPE_ALARM_GEOFENCE: content.writeShort(command.getInteger(Command.KEY_RADIUS)); return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_MOVEMENT_ALARM, content); diff --git a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java index 5b72f6f1f..1f2e5f7e3 100644 --- a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java @@ -36,6 +36,10 @@ public class MeiligaoProtocolEncoderTest extends ProtocolTest { verifyCommand(encoder, command, binary("4040001312345678901234410603e87bb00d0a")); + command.setType(Command.TYPE_ENGINE_STOP); + + verifyCommand(encoder, command, binary("4040001212345678901234411501fd460d0a")); + } } -- cgit v1.2.3 From 9280355123ee13f7f7d8bf7076a39dcab57ab1cd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 2 Nov 2022 17:57:22 -0700 Subject: Improve attribute type handling --- src/main/java/org/traccar/model/ExtendedModel.java | 30 ++++++++++++++++++---- .../org/traccar/protocol/KhdProtocolEncoder.java | 2 +- .../traccar/protocol/MeiligaoProtocolEncoder.java | 6 ++--- .../traccar/protocol/RuptelaProtocolEncoder.java | 4 +-- .../traccar/protocol/SuntechProtocolEncoder.java | 16 ++++++------ 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index ef2e3b68f..7a61eda8c 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -91,7 +91,7 @@ public class ExtendedModel extends BaseModel { public String getString(String key) { if (attributes.containsKey(key)) { - return (String) attributes.get(key); + return attributes.get(key).toString(); } else { return null; } @@ -99,7 +99,12 @@ public class ExtendedModel extends BaseModel { public double getDouble(String key) { if (attributes.containsKey(key)) { - return ((Number) attributes.get(key)).doubleValue(); + Object value = attributes.get(key); + if (value instanceof Number) { + return ((Number) attributes.get(key)).doubleValue(); + } else { + return Double.parseDouble(value.toString()); + } } else { return 0.0; } @@ -107,7 +112,12 @@ public class ExtendedModel extends BaseModel { public boolean getBoolean(String key) { if (attributes.containsKey(key)) { - return (Boolean) attributes.get(key); + Object value = attributes.get(key); + if (value instanceof Boolean) { + return (Boolean) attributes.get(key); + } else { + return Boolean.parseBoolean(value.toString()); + } } else { return false; } @@ -115,7 +125,12 @@ public class ExtendedModel extends BaseModel { public int getInteger(String key) { if (attributes.containsKey(key)) { - return ((Number) attributes.get(key)).intValue(); + Object value = attributes.get(key); + if (value instanceof Number) { + return ((Number) attributes.get(key)).intValue(); + } else { + return Integer.parseInt(value.toString()); + } } else { return 0; } @@ -123,7 +138,12 @@ public class ExtendedModel extends BaseModel { public long getLong(String key) { if (attributes.containsKey(key)) { - return ((Number) attributes.get(key)).longValue(); + Object value = attributes.get(key); + if (value instanceof Number) { + return ((Number) attributes.get(key)).longValue(); + } else { + return Long.parseLong(value.toString()); + } } else { return 0; } diff --git a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java index 8aeb9660d..12353b415 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java @@ -84,7 +84,7 @@ public class KhdProtocolEncoder extends BaseProtocolEncoder { return encodeCommand(MSG_FACTORY_RESET, uniqueId, null); case Command.TYPE_SET_SPEED_LIMIT: ByteBuf content = Unpooled.buffer(); - content.writeByte(Integer.parseInt(command.getString(Command.KEY_DATA))); + content.writeByte(command.getInteger(Command.KEY_DATA)); return encodeCommand(MSG_RESUME_OIL, uniqueId, content); case Command.TYPE_SET_ODOMETER: return encodeCommand(MSG_DELETE_MILEAGE, uniqueId, null); diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java index 03f0e7ecf..5859d91ce 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 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,8 +99,8 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { content.writeShort(command.getInteger(Command.KEY_FREQUENCY) / 10); return encodeContent(command.getDeviceId(), MeiligaoProtocolDecoder.MSG_TRACK_BY_INTERVAL, content); case Command.TYPE_OUTPUT_CONTROL: - int index = Integer.parseInt(command.getString(Command.KEY_INDEX)) - 1; - int value = Integer.parseInt(command.getString(Command.KEY_DATA)); + int index = command.getInteger(Command.KEY_INDEX) - 1; + int value = command.getInteger(Command.KEY_DATA); return encodeOutputCommand(command.getDeviceId(), index, value); case Command.TYPE_ENGINE_STOP: return encodeOutputCommand(command.getDeviceId(), 1, 1); diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java index 442961b19..5ec971a98 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java @@ -80,14 +80,14 @@ public class RuptelaProtocolEncoder extends BaseProtocolEncoder { return encodeContent(RuptelaProtocolDecoder.MSG_FIRMWARE_UPDATE, content); case Command.TYPE_OUTPUT_CONTROL: content.writeInt(command.getInteger(Command.KEY_INDEX)); - content.writeInt(Integer.parseInt(command.getString(Command.KEY_DATA))); + content.writeInt(command.getInteger(Command.KEY_DATA)); return encodeContent(RuptelaProtocolDecoder.MSG_SET_IO, content); case Command.TYPE_SET_CONNECTION: String c = command.getString(Command.KEY_SERVER) + "," + command.getInteger(Command.KEY_PORT) + ",TCP"; content.writeBytes(c.getBytes(StandardCharsets.US_ASCII)); return encodeContent(RuptelaProtocolDecoder.MSG_SET_CONNECTION, content); case Command.TYPE_SET_ODOMETER: - content.writeInt(Integer.parseInt(command.getString(Command.KEY_DATA))); + content.writeInt(command.getInteger(Command.KEY_DATA)); return encodeContent(RuptelaProtocolDecoder.MSG_SET_ODOMETER, content); default: return null; diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java index 53308f968..b298adc5a 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java @@ -59,23 +59,23 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { return formatCommand(command, "CMD;%s;03;01\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { - switch (command.getString(Command.KEY_INDEX)) { - case "1": + switch (command.getInteger(Command.KEY_INDEX)) { + case 1: return formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); - case "2": + case 2: return formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); - case "3": + case 3: return formatCommand(command, "CMD;%s;04;09\r", Command.KEY_UNIQUE_ID); default: return null; } } else { - switch (command.getString(Command.KEY_INDEX)) { - case "1": + switch (command.getInteger(Command.KEY_INDEX)) { + case 1: return formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); - case "2": + case 2: return formatCommand(command, "CMD;%s;04;04\r", Command.KEY_UNIQUE_ID); - case "3": + case 3: return formatCommand(command, "CMD;%s;04;10\r", Command.KEY_UNIQUE_ID); default: return null; -- cgit v1.2.3 From 9c03a0505f46a92f645dc927dba2da6458facfb1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Nov 2022 20:29:36 -0700 Subject: Reuse checksum code --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 8a58ebc5e..8e5269ec8 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -363,17 +363,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { positions.add(position); } - if (channel != null) { + if (channel == null) { StringBuilder command = new StringBuilder("@@"); command.append(flag).append(27 + positions.size() / 10).append(","); command.append(imei).append(",CCC,").append(positions.size()).append("*"); - int checksum = 0; - for (int i = 0; i < command.length(); i += 1) { - checksum += command.charAt(i); - } - command.append(String.format("%02x", checksum & 0xff).toUpperCase()); + command.append(Checksum.sum(command.toString())); command.append("\r\n"); - channel.writeAndFlush(new NetworkMessage(command.toString(), remoteAddress)); // delete processed data + channel.writeAndFlush(new NetworkMessage(command.toString(), remoteAddress)); } return positions; -- cgit v1.2.3 From fdd52edc7811ae973c93ae825cc1bd1d9e9fe33f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Nov 2022 20:30:00 -0700 Subject: Fix response --- src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 8e5269ec8..736f5871c 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -363,7 +363,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { positions.add(position); } - if (channel == null) { + if (channel != null) { StringBuilder command = new StringBuilder("@@"); command.append(flag).append(27 + positions.size() / 10).append(","); command.append(imei).append(",CCC,").append(positions.size()).append("*"); -- cgit v1.2.3 From e742f252da0b32ac7166c6d9ab25a8d1375411d2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Nov 2022 20:36:25 -0700 Subject: Add MD500S heartbeat response --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 13 ++++++++++--- .../org/traccar/protocol/MeitrackProtocolDecoderTest.java | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 736f5871c..1935b2c2a 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -538,13 +538,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { return positions; } - private void requestPhotoPacket(Channel channel, SocketAddress socketAddress, String imei, String file, int index) { + private void requestPhotoPacket(Channel channel, SocketAddress remoteAddress, String imei, String file, int index) { if (channel != null) { String content = "D00," + file + "," + index; int length = 1 + imei.length() + 1 + content.length() + 5; String response = String.format("@@O%02d,%s,%s*", length, imei, content); response += Checksum.sum(response) + "\r\n"; - channel.writeAndFlush(new NetworkMessage(response, socketAddress)); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } } @@ -560,6 +560,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { String type = buf.toString(index + 1, 3, StandardCharsets.US_ASCII); switch (type) { + case "AAC": + if (channel != null) { + String response = String.format("@@z27,%s,AAC,1*", imei); + response += Checksum.sum(response) + "\r\n"; + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + return null; case "D00": if (photo == null) { photo = Unpooled.buffer(); diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 0fc51b8b6..67b83ebd9 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -129,6 +129,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "2424473937302c3336393830303031333436303637342c4343432c020134005b000000010ce304035db9e000ec6f591a000013000000000c001801edb70200c96d0100e60001004838576501000300a101c20400000000010ce304035db9e000ee6f591a000013000000000c001801edb70200ca6d0100e60001004838576501000300a101c20400000000010ce304035db9e000ef6f591a000013000000000c001801edb70200cc6d0100e60001004838576501000300a101c20400000000020ce304035db9e000f76f591a000016000000000c001801edb70200d36d0100e60001004838576502000300a101bf04000000000a0ce304035db9e000f76f591a000016000000000c001801edb70200d46d0100e60001004838576500000300a101bf0400000000020ce304035db9e000fb6f591a000016000000000c001801edb70200d86d0100e60001004838576502000300a101760400000000180ce304035db9e000fc6f591a0000120000000000008c00edb70200d96d0100e60001004838576502000300a10176040000000019b1e2040323b9e0000b70591a0105150600bb0012002901edb70200e76d0100e60001004838576502000300a2017005000000002023e304031fb9e0001070591a010615070027010d001601fcb70200ec6d0100e60001004838576502000300a201800500000000201fe3040302b9e0001170591a010615090019010d001501feb70200ed6d0100e60001004838576502000300a2018005000000002018e30403dcb8e0001270591a0106150b0011010d00150100b80200ee6d0100e60001004838576502000300a2018005000000002036e3040345b8e0001570591a0107150b002d010b0013010ab80200f16d0100e60001004838576502000300a2018005000000002053e3040326b8e0001670591a0107150d0041010b0013010eb80200f26d0100e60001004838576502000300a2018005000000002070e3040310b8e0001770591a0107150e004f010b00130111b80200f36d0100e60001004838576502000300a2018005000000002095e3040306b8e0001870591a0107150d005a010b00140115b80200f46d0100e60001004838576502000300a20180050000000020b3e3040305b8e0001970591a0107150b0060010b00140118b80200f56d0100e60001004838576502000300a20183050000000020cfe3040308b8e0001a70591a0107150b0066010b0014011bb80200f66d0100e60001004838576502000300a20183050000000020eee304030cb8e0001b70591a0106170b0004000d0014011eb80200f76d0100e60001004838576502000300a2018305000000002a62350d0a")); + verifyNull(decoder, buffer( + "$$z27,861451040910625,AAC,1*D3")); + } } -- cgit v1.2.3 From 21a916159a24db0cbec850b90381f9ff392f3c0e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Nov 2022 08:55:31 -0700 Subject: Clean up command resource --- src/main/java/org/traccar/api/resource/CommandResource.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/api/resource/CommandResource.java b/src/main/java/org/traccar/api/resource/CommandResource.java index 80b9fd18f..6ef6ee9c5 100644 --- a/src/main/java/org/traccar/api/resource/CommandResource.java +++ b/src/main/java/org/traccar/api/resource/CommandResource.java @@ -84,10 +84,10 @@ public class CommandResource extends ExtendedObjectResource { permissionsService.checkPermission(Device.class, getUserId(), deviceId); BaseProtocol protocol = getDeviceProtocol(deviceId); - var commands = storage.getObjects(Command.class, new Request( + var commands = storage.getObjects(baseClass, new Request( new Columns.All(), Condition.merge(List.of( - new Condition.Permission(User.class, getUserId(), Command.class), + new Condition.Permission(User.class, getUserId(), baseClass), new Condition.Permission(Device.class, deviceId, baseClass) )))); @@ -107,7 +107,7 @@ public class CommandResource extends ExtendedObjectResource { public Response send(Command entity) throws Exception { permissionsService.checkRestriction(getUserId(), UserRestrictions::getReadonly); if (entity.getId() > 0) { - permissionsService.checkPermission(Command.class, getUserId(), entity.getId()); + permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); long deviceId = entity.getDeviceId(); entity = storage.getObject(baseClass, new Request( new Columns.All(), new Condition.Equals("id", entity.getId()))); -- cgit v1.2.3 From d0df0c2e33034efee4a3a0705c92b09dbed5e291 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 6 Nov 2022 10:01:50 -0800 Subject: Handle missing cache --- .../org/traccar/session/cache/CacheManager.java | 24 +++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 8f2e7ba93..dc7382223 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -15,6 +15,8 @@ */ package org.traccar.session.cache; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastInterface; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; @@ -42,6 +44,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; @@ -57,6 +60,7 @@ import java.util.stream.Collectors; @Singleton public class CacheManager implements BroadcastInterface { + private static final Logger LOGGER = LoggerFactory.getLogger(CacheManager.class); private static final int GROUP_DEPTH_LIMIT = 3; private static final Collection> CLASSES = Arrays.asList( Attribute.class, Driver.class, Geofence.class, Maintenance.class, Notification.class); @@ -102,13 +106,19 @@ public class CacheManager implements BroadcastInterface { public List getDeviceObjects(long deviceId, Class clazz) { try { lock.readLock().lock(); - return deviceLinks.get(deviceId).get(clazz).stream() - .map(id -> { - var cacheValue = deviceCache.get(new CacheKey(clazz, id)); - return cacheValue != null ? cacheValue.getValue() : null; - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + var links = deviceLinks.get(deviceId); + if (links != null) { + return links.getOrDefault(clazz, new LinkedHashSet<>()).stream() + .map(id -> { + var cacheValue = deviceCache.get(new CacheKey(clazz, id)); + return cacheValue != null ? cacheValue.getValue() : null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } else { + LOGGER.warn("Device {} cache missing", deviceId); + return Collections.emptyList(); + } } finally { lock.readLock().unlock(); } -- cgit v1.2.3 From d9d990b492896d7e42a503c002de7715f6d12a30 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 10 Nov 2022 08:29:10 -0800 Subject: Add comment --- src/main/java/org/traccar/WebDataHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index 9b26c8875..2d2e3dc8f 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -126,6 +126,7 @@ public class WebDataHandler extends BaseDataHandler { return s.toString(); } + // OpenGTS status code private String calculateStatus(Position position) { if (position.hasAttribute(Position.KEY_ALARM)) { return "0xF841"; // STATUS_PANIC_ON -- cgit v1.2.3 From 4ec9db613475066de3f46c24d4ee78fefcbb17df Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Nov 2022 09:19:16 -0800 Subject: Fix manager permission (fix #4982) --- src/main/java/org/traccar/api/security/PermissionsService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 71acb3d48..37bb6fd72 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -34,6 +34,7 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import javax.inject.Inject; +import java.util.Objects; @RequestScoped public class PermissionsService { @@ -158,6 +159,7 @@ public class PermissionsService { } User user = getUser(userId); if (user != null && user.getExpirationTime() != null + && !Objects.equals(before.getExpirationTime(), after.getExpirationTime()) && (after.getExpirationTime() == null || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) { checkAdmin(userId); -- cgit v1.2.3 From ff793b2e2872f8ba076e748fab41d944f92b64d4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Nov 2022 10:12:32 -0800 Subject: Refactor event forwarding --- src/main/java/org/traccar/MainModule.java | 7 +- .../org/traccar/database/NotificationManager.java | 20 +++- src/main/java/org/traccar/forward/EventData.java | 78 +++++++++++++++ .../java/org/traccar/forward/EventForwarder.java | 20 ++++ .../org/traccar/forward/EventForwarderJson.java | 66 +++++++++++++ .../org/traccar/notification/EventForwarder.java | 109 --------------------- 6 files changed, 186 insertions(+), 114 deletions(-) create mode 100644 src/main/java/org/traccar/forward/EventData.java create mode 100644 src/main/java/org/traccar/forward/EventForwarder.java create mode 100644 src/main/java/org/traccar/forward/EventForwarderJson.java delete mode 100644 src/main/java/org/traccar/notification/EventForwarder.java diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index c4cda578e..9a5cca4c7 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -35,6 +35,8 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; +import org.traccar.forward.EventForwarder; +import org.traccar.forward.EventForwarderJson; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; import org.traccar.geocoder.BingMapsGeocoder; @@ -67,7 +69,6 @@ import org.traccar.helper.SanitizerModule; import org.traccar.mail.LogMailManager; import org.traccar.mail.MailManager; import org.traccar.mail.SmtpMailManager; -import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; @@ -310,9 +311,9 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static EventForwarder provideEventForwarder(Config config, Client client, CacheManager cacheManager) { + public static EventForwarder provideEventForwarder(Config config, Client client) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - return new EventForwarder(config, client, cacheManager); + return new EventForwarderJson(config, client); } return null; } diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 5ea89fcac..7c82454b2 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -20,12 +20,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.forward.EventData; +import org.traccar.forward.EventForwarder; import org.traccar.geocoder.Geocoder; import org.traccar.model.Calendar; import org.traccar.model.Event; +import org.traccar.model.Geofence; +import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.Position; -import org.traccar.notification.EventForwarder; import org.traccar.notification.MessageException; import org.traccar.notification.NotificatorManager; import org.traccar.session.cache.CacheManager; @@ -112,8 +115,21 @@ public class NotificationManager { }); } + forwardEvent(event, position); + } + + private void forwardEvent(Event event, Position position) { if (eventForwarder != null) { - eventForwarder.forwardEvent(event, position); + EventData eventData = new EventData(); + eventData.setEvent(event); + eventData.setPosition(position); + if (event.getGeofenceId() != 0) { + eventData.setGeofence(cacheManager.getObject(Geofence.class, event.getGeofenceId())); + } + if (event.getMaintenanceId() != 0) { + eventData.setMaintenance(cacheManager.getObject(Maintenance.class, event.getMaintenanceId())); + } + eventForwarder.forward(eventData); } } diff --git a/src/main/java/org/traccar/forward/EventData.java b/src/main/java/org/traccar/forward/EventData.java new file mode 100644 index 000000000..4471b10b3 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventData.java @@ -0,0 +1,78 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +import com.fasterxml.jackson.annotation.JsonInclude; +import org.traccar.model.Device; +import org.traccar.model.Event; +import org.traccar.model.Geofence; +import org.traccar.model.Maintenance; +import org.traccar.model.Position; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class EventData { + + private Event event; + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + + private Position position; + + public Position getPosition() { + return position; + } + + public void setPosition(Position position) { + this.position = position; + } + + private Device device; + + public Device getDevice() { + return device; + } + + public void setDevice(Device device) { + this.device = device; + } + + private Geofence geofence; + + public Geofence getGeofence() { + return geofence; + } + + public void setGeofence(Geofence geofence) { + this.geofence = geofence; + } + + private Maintenance maintenance; + + public Maintenance getMaintenance() { + return maintenance; + } + + public void setMaintenance(Maintenance maintenance) { + this.maintenance = maintenance; + } + +} diff --git a/src/main/java/org/traccar/forward/EventForwarder.java b/src/main/java/org/traccar/forward/EventForwarder.java new file mode 100644 index 000000000..c3ad5efc0 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventForwarder.java @@ -0,0 +1,20 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +public interface EventForwarder { + void forward(EventData eventData); +} diff --git a/src/main/java/org/traccar/forward/EventForwarderJson.java b/src/main/java/org/traccar/forward/EventForwarderJson.java new file mode 100644 index 000000000..c136fd4e2 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventForwarderJson.java @@ -0,0 +1,66 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Inject; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.InvocationCallback; + +public class EventForwarderJson implements EventForwarder { + + private static final Logger LOGGER = LoggerFactory.getLogger(EventForwarderJson.class); + + private final String url; + private final String header; + + private final Client client; + + @Inject + public EventForwarderJson(Config config, Client client) { + this.client = client; + url = config.getString(Keys.EVENT_FORWARD_URL); + header = config.getString(Keys.EVENT_FORWARD_HEADERS); + } + + public void forward(EventData eventData) { + var requestBuilder = client.target(url).request(); + + if (header != null && !header.isEmpty()) { + for (String line: header.split("\\r?\\n")) { + String[] values = line.split(":", 2); + requestBuilder.header(values[0].trim(), values[1].trim()); + } + } + + requestBuilder.async().post(Entity.json(eventData), new InvocationCallback<>() { + @Override + public void completed(Object o) { + } + + @Override + public void failed(Throwable throwable) { + LOGGER.warn("Event forwarding failed", throwable); + } + }); + } + +} diff --git a/src/main/java/org/traccar/notification/EventForwarder.java b/src/main/java/org/traccar/notification/EventForwarder.java deleted file mode 100644 index 50f17a852..000000000 --- a/src/main/java/org/traccar/notification/EventForwarder.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2016 - 2022 Anton Tananaev (anton@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.notification; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.model.Device; -import org.traccar.model.Event; -import org.traccar.model.Geofence; -import org.traccar.model.Maintenance; -import org.traccar.model.Position; -import org.traccar.session.cache.CacheManager; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.InvocationCallback; -import java.util.HashMap; -import java.util.Map; - -public class EventForwarder { - - private static final Logger LOGGER = LoggerFactory.getLogger(EventForwarder.class); - - private final String url; - private final String header; - - private final Client client; - private final CacheManager cacheManager; - - public EventForwarder(Config config, Client client, CacheManager cacheManager) { - this.client = client; - this.cacheManager = cacheManager; - url = config.getString(Keys.EVENT_FORWARD_URL); - header = config.getString(Keys.EVENT_FORWARD_HEADERS); - } - - private static final String KEY_POSITION = "position"; - private static final String KEY_EVENT = "event"; - private static final String KEY_GEOFENCE = "geofence"; - private static final String KEY_DEVICE = "device"; - private static final String KEY_MAINTENANCE = "maintenance"; - - public final void forwardEvent(Event event, Position position) { - - Invocation.Builder requestBuilder = client.target(url).request(); - - if (header != null && !header.isEmpty()) { - for (String line: header.split("\\r?\\n")) { - String[] values = line.split(":", 2); - requestBuilder.header(values[0].trim(), values[1].trim()); - } - } - - LOGGER.debug("Event forwarding initiated"); - requestBuilder.async().post(Entity.json(preparePayload(event, position)), new InvocationCallback<>() { - @Override - public void completed(Object o) { - LOGGER.debug("Event forwarding succeeded"); - } - - @Override - public void failed(Throwable throwable) { - LOGGER.warn("Event forwarding failed", throwable); - } - }); - } - - protected Map preparePayload(Event event, Position position) { - Map data = new HashMap<>(); - data.put(KEY_EVENT, event); - if (position != null) { - data.put(KEY_POSITION, position); - } - Device device = cacheManager.getObject(Device.class, event.getDeviceId()); - if (device != null) { - data.put(KEY_DEVICE, device); - } - if (event.getGeofenceId() != 0) { - Geofence geofence = cacheManager.getObject(Geofence.class, event.getGeofenceId()); - if (geofence != null) { - data.put(KEY_GEOFENCE, geofence); - } - } - if (event.getMaintenanceId() != 0) { - Maintenance maintenance = cacheManager.getObject(Maintenance.class, event.getMaintenanceId()); - if (maintenance != null) { - data.put(KEY_MAINTENANCE, maintenance); - } - } - return data; - } - -} -- cgit v1.2.3 From 5877cb1b3f1fa7331c4310b9754a3ec442586497 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Nov 2022 11:48:43 -0800 Subject: Refactor position forwarding --- src/main/java/org/traccar/BasePipelineFactory.java | 2 +- src/main/java/org/traccar/MainModule.java | 16 ++ .../org/traccar/PositionForwardingHandler.java | 141 +++++++++ src/main/java/org/traccar/WebDataHandler.java | 316 --------------------- src/main/java/org/traccar/config/Keys.java | 17 +- .../org/traccar/database/NotificationManager.java | 6 +- .../java/org/traccar/forward/EventForwarder.java | 2 +- .../org/traccar/forward/EventForwarderJson.java | 22 +- .../java/org/traccar/forward/PositionData.java | 45 +++ .../org/traccar/forward/PositionForwarder.java | 20 ++ .../org/traccar/forward/PositionForwarderJson.java | 86 ++++++ .../org/traccar/forward/PositionForwarderUrl.java | 166 +++++++++++ .../java/org/traccar/forward/ResultHandler.java | 20 ++ src/test/java/org/traccar/WebDataHandlerTest.java | 42 --- .../traccar/forward/PositionForwarderUrlTest.java | 42 +++ 15 files changed, 561 insertions(+), 382 deletions(-) create mode 100644 src/main/java/org/traccar/PositionForwardingHandler.java delete mode 100644 src/main/java/org/traccar/WebDataHandler.java create mode 100644 src/main/java/org/traccar/forward/PositionData.java create mode 100644 src/main/java/org/traccar/forward/PositionForwarder.java create mode 100644 src/main/java/org/traccar/forward/PositionForwarderJson.java create mode 100644 src/main/java/org/traccar/forward/PositionForwarderUrl.java create mode 100644 src/main/java/org/traccar/forward/ResultHandler.java delete mode 100644 src/test/java/org/traccar/WebDataHandlerTest.java create mode 100644 src/test/java/org/traccar/forward/PositionForwarderUrlTest.java diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 0d91ec7e4..b184da45c 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -140,7 +140,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { CopyAttributesHandler.class, EngineHoursHandler.class, ComputedAttributesHandler.class, - WebDataHandler.class, + PositionForwardingHandler.class, DefaultDataHandler.class, MediaEventHandler.class, CommandResultEventHandler.class, diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 9a5cca4c7..9d450fef7 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -37,6 +37,9 @@ import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.forward.EventForwarder; import org.traccar.forward.EventForwarderJson; +import org.traccar.forward.PositionForwarder; +import org.traccar.forward.PositionForwarderJson; +import org.traccar.forward.PositionForwarderUrl; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; import org.traccar.geocoder.BingMapsGeocoder; @@ -318,6 +321,19 @@ public class MainModule extends AbstractModule { return null; } + @Singleton + @Provides + public static PositionForwarder providePositionForwarder(Config config, Client client, ObjectMapper objectMapper) { + if (config.hasKey(Keys.FORWARD_URL)) { + if (config.getBoolean(Keys.FORWARD_JSON)) { + return new PositionForwarderJson(config, client, objectMapper); + } else { + return new PositionForwarderUrl(config, client, objectMapper); + } + } + return null; + } + @Singleton @Provides public static VelocityEngine provideVelocityEngine(Config config) { diff --git a/src/main/java/org/traccar/PositionForwardingHandler.java b/src/main/java/org/traccar/PositionForwardingHandler.java new file mode 100644 index 000000000..83f91e937 --- /dev/null +++ b/src/main/java/org/traccar/PositionForwardingHandler.java @@ -0,0 +1,141 @@ +/* + * Copyright 2015 - 2022 Anton Tananaev (anton@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; + +import io.netty.channel.ChannelHandler; +import io.netty.util.Timeout; +import io.netty.util.Timer; +import io.netty.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.forward.PositionData; +import org.traccar.forward.PositionForwarder; +import org.traccar.forward.ResultHandler; +import org.traccar.model.Device; +import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +@Singleton +@ChannelHandler.Sharable +public class PositionForwardingHandler extends BaseDataHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(PositionForwardingHandler.class); + + private final CacheManager cacheManager; + private final Timer timer; + + private final PositionForwarder positionForwarder; + + private final boolean retryEnabled; + private final int retryDelay; + private final int retryCount; + private final int retryLimit; + + private final AtomicInteger deliveryPending; + + @Inject + public PositionForwardingHandler( + Config config, CacheManager cacheManager, Timer timer, @Nullable PositionForwarder positionForwarder) { + + this.cacheManager = cacheManager; + this.timer = timer; + this.positionForwarder = positionForwarder; + + this.retryEnabled = config.getBoolean(Keys.FORWARD_RETRY_ENABLE); + this.retryDelay = config.getInteger(Keys.FORWARD_RETRY_DELAY); + this.retryCount = config.getInteger(Keys.FORWARD_RETRY_COUNT); + this.retryLimit = config.getInteger(Keys.FORWARD_RETRY_LIMIT); + + this.deliveryPending = new AtomicInteger(); + } + + class AsyncRequestAndCallback implements ResultHandler, TimerTask { + + private final PositionData positionData; + + private int retries = 0; + + AsyncRequestAndCallback(PositionData positionData) { + this.positionData = positionData; + deliveryPending.incrementAndGet(); + } + + private void send() { + positionForwarder.forward(positionData, this); + } + + private void retry(Throwable throwable) { + boolean scheduled = false; + try { + if (retryEnabled && deliveryPending.get() <= retryLimit && retries < retryCount) { + schedule(); + scheduled = true; + } + } finally { + int pending = scheduled ? deliveryPending.get() : deliveryPending.decrementAndGet(); + LOGGER.warn("Position forwarding failed: " + pending + " pending", throwable); + } + } + + private void schedule() { + timer.newTimeout(this, retryDelay * (long) Math.pow(2, retries++), TimeUnit.MILLISECONDS); + } + + @Override + public void onResult(boolean success, Throwable throwable) { + if (success) { + deliveryPending.decrementAndGet(); + } else { + retry(throwable); + } + } + + @Override + public void run(Timeout timeout) { + boolean sent = false; + try { + if (!timeout.isCancelled()) { + send(); + sent = true; + } + } finally { + if (!sent) { + deliveryPending.decrementAndGet(); + } + } + } + } + + @Override + protected Position handlePosition(Position position) { + if (positionForwarder != null) { + PositionData positionData = new PositionData(); + positionData.setPosition(position); + positionData.setDevice(cacheManager.getObject(Device.class, position.getDeviceId())); + new AsyncRequestAndCallback(positionData).send(); + } + return position; + } + +} diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java deleted file mode 100644 index 2d2e3dc8f..000000000 --- a/src/main/java/org/traccar/WebDataHandler.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright 2015 - 2022 Anton Tananaev (anton@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; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.netty.channel.ChannelHandler; -import io.netty.util.Timer; -import io.netty.util.Timeout; -import io.netty.util.TimerTask; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.helper.Checksum; -import org.traccar.model.Device; -import org.traccar.model.Position; -import org.traccar.model.Group; -import org.traccar.session.cache.CacheManager; - -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.client.InvocationCallback; -import java.util.HashMap; -import java.util.Map; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.Calendar; -import java.util.Formatter; -import java.util.Locale; -import java.util.TimeZone; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -@Singleton -@ChannelHandler.Sharable -public class WebDataHandler extends BaseDataHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(WebDataHandler.class); - - private static final String KEY_POSITION = "position"; - private static final String KEY_DEVICE = "device"; - - private final CacheManager cacheManager; - private final ObjectMapper objectMapper; - private final Client client; - private final Timer timer; - - private final String url; - private final String header; - private final boolean json; - private final boolean urlVariables; - - private final boolean retryEnabled; - private final int retryDelay; - private final int retryCount; - private final int retryLimit; - - private final AtomicInteger deliveryPending; - - @Inject - public WebDataHandler( - Config config, CacheManager cacheManager, ObjectMapper objectMapper, Client client, Timer timer) { - - this.cacheManager = cacheManager; - this.objectMapper = objectMapper; - this.client = client; - this.timer = timer; - this.url = config.getString(Keys.FORWARD_URL); - this.header = config.getString(Keys.FORWARD_HEADER); - this.json = config.getBoolean(Keys.FORWARD_JSON); - this.urlVariables = config.getBoolean(Keys.FORWARD_URL_VARIABLES); - - this.retryEnabled = config.getBoolean(Keys.FORWARD_RETRY_ENABLE); - this.retryDelay = config.getInteger(Keys.FORWARD_RETRY_DELAY, 100); - this.retryCount = config.getInteger(Keys.FORWARD_RETRY_COUNT, 10); - this.retryLimit = config.getInteger(Keys.FORWARD_RETRY_LIMIT, 100); - - this.deliveryPending = new AtomicInteger(0); - } - - private static String formatSentence(Position position) { - - StringBuilder s = new StringBuilder("$GPRMC,"); - - try (Formatter f = new Formatter(s, Locale.ENGLISH)) { - - Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ENGLISH); - calendar.setTimeInMillis(position.getFixTime().getTime()); - - f.format("%1$tH%1$tM%1$tS.%1$tL,A,", calendar); - - double lat = position.getLatitude(); - double lon = position.getLongitude(); - - f.format("%02d%07.4f,%c,", (int) Math.abs(lat), Math.abs(lat) % 1 * 60, lat < 0 ? 'S' : 'N'); - f.format("%03d%07.4f,%c,", (int) Math.abs(lon), Math.abs(lon) % 1 * 60, lon < 0 ? 'W' : 'E'); - - f.format("%.2f,%.2f,", position.getSpeed(), position.getCourse()); - f.format("%1$td%1$tm%1$ty,,", calendar); - } - - s.append(Checksum.nmea(s.substring(1))); - - return s.toString(); - } - - // OpenGTS status code - private String calculateStatus(Position position) { - if (position.hasAttribute(Position.KEY_ALARM)) { - return "0xF841"; // STATUS_PANIC_ON - } else if (position.getSpeed() < 1.0) { - return "0xF020"; // STATUS_LOCATION - } else { - return "0xF11C"; // STATUS_MOTION_MOVING - } - } - - public String formatRequest(Position position) throws UnsupportedEncodingException, JsonProcessingException { - - Device device = cacheManager.getObject(Device.class, position.getDeviceId()); - - String request = url - .replace("{name}", URLEncoder.encode(device.getName(), StandardCharsets.UTF_8.name())) - .replace("{uniqueId}", device.getUniqueId()) - .replace("{status}", device.getStatus()) - .replace("{deviceId}", String.valueOf(position.getDeviceId())) - .replace("{protocol}", String.valueOf(position.getProtocol())) - .replace("{deviceTime}", String.valueOf(position.getDeviceTime().getTime())) - .replace("{fixTime}", String.valueOf(position.getFixTime().getTime())) - .replace("{valid}", String.valueOf(position.getValid())) - .replace("{latitude}", String.valueOf(position.getLatitude())) - .replace("{longitude}", String.valueOf(position.getLongitude())) - .replace("{altitude}", String.valueOf(position.getAltitude())) - .replace("{speed}", String.valueOf(position.getSpeed())) - .replace("{course}", String.valueOf(position.getCourse())) - .replace("{accuracy}", String.valueOf(position.getAccuracy())) - .replace("{statusCode}", calculateStatus(position)); - - if (position.getAddress() != null) { - request = request.replace( - "{address}", URLEncoder.encode(position.getAddress(), StandardCharsets.UTF_8.name())); - } - - if (request.contains("{attributes}")) { - String attributes = objectMapper.writeValueAsString(position.getAttributes()); - request = request.replace( - "{attributes}", URLEncoder.encode(attributes, StandardCharsets.UTF_8.name())); - } - - if (request.contains("{gprmc}")) { - request = request.replace("{gprmc}", formatSentence(position)); - } - - if (request.contains("{group}")) { - String deviceGroupName = ""; - if (device.getGroupId() != 0) { - Group group = cacheManager.getObject(Group.class, device.getGroupId()); - if (group != null) { - deviceGroupName = group.getName(); - } - } - - request = request.replace("{group}", URLEncoder.encode(deviceGroupName, StandardCharsets.UTF_8.name())); - } - - return request; - } - - class AsyncRequestAndCallback implements InvocationCallback, TimerTask { - - private int retries = 0; - private Map payload; - private final Invocation.Builder requestBuilder; - private MediaType mediaType = MediaType.APPLICATION_JSON_TYPE; - - AsyncRequestAndCallback(Position position) { - - String formattedUrl; - try { - formattedUrl = json && !urlVariables ? url : formatRequest(position); - } catch (UnsupportedEncodingException | JsonProcessingException e) { - throw new RuntimeException("Forwarding formatting error", e); - } - - requestBuilder = client.target(formattedUrl).request(); - if (header != null && !header.isEmpty()) { - for (String line: header.split("\\r?\\n")) { - String[] values = line.split(":", 2); - String headerName = values[0].trim(); - String headerValue = values[1].trim(); - if (headerName.equals(HttpHeaders.CONTENT_TYPE)) { - mediaType = MediaType.valueOf(headerValue); - } else { - requestBuilder.header(headerName, headerValue); - } - } - } - - if (json) { - payload = prepareJsonPayload(position); - } - - deliveryPending.incrementAndGet(); - } - - private void send() { - LOGGER.debug("Position forwarding initiated"); - if (json) { - try { - Entity entity = Entity.entity(objectMapper.writeValueAsString(payload), mediaType); - requestBuilder.async().post(entity, this); - } catch (JsonProcessingException e) { - throw new RuntimeException("Failed to serialize location to json", e); - } - } else { - requestBuilder.async().get(this); - } - } - - private void retry(Throwable throwable) { - boolean scheduled = false; - try { - if (retryEnabled && deliveryPending.get() <= retryLimit && retries < retryCount) { - schedule(); - scheduled = true; - } - } finally { - int pending = scheduled ? deliveryPending.get() : deliveryPending.decrementAndGet(); - LOGGER.warn("Position forwarding failed: " + pending + " pending", throwable); - } - } - - private void schedule() { - timer.newTimeout(this, retryDelay * (long) Math.pow(2, retries++), TimeUnit.MILLISECONDS); - } - - @Override - public void completed(Response response) { - if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) { - deliveryPending.decrementAndGet(); - LOGGER.debug("Position forwarding succeeded"); - } else { - retry(new RuntimeException("Status code 2xx expected")); - } - } - - @Override - public void failed(Throwable throwable) { - retry(throwable); - } - - @Override - public void run(Timeout timeout) { - boolean sent = false; - try { - if (!timeout.isCancelled()) { - send(); - sent = true; - } - } finally { - if (!sent) { - deliveryPending.decrementAndGet(); - } - } - } - - } - - @Override - protected Position handlePosition(Position position) { - - if (url != null) { - AsyncRequestAndCallback request = new AsyncRequestAndCallback(position); - request.send(); - } - - return position; - } - - private Map prepareJsonPayload(Position position) { - - Map data = new HashMap<>(); - Device device = cacheManager.getObject(Device.class, position.getDeviceId()); - - data.put(KEY_POSITION, position); - - if (device != null) { - data.put(KEY_DEVICE, device); - } - - return data; - } - -} diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 1da01518c..b60cd82a0 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -720,14 +720,6 @@ public final class Keys { "forward.json", List.of(KeyType.CONFIG)); - /** - * Boolean value to enable URL parameters in json mode. For example, {uniqueId} for device identifier, - * {latitude} and {longitude} for coordinates. - */ - public static final ConfigKey FORWARD_URL_VARIABLES = new BooleanConfigKey( - "forward.urlVariables", - List.of(KeyType.CONFIG)); - /** * Position forwarding retrying enable. When enabled, additional attempts are made to deliver positions. If initial * delivery fails, because of an unreachable server or an HTTP response different from '2xx', the software waits @@ -745,7 +737,8 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_DELAY = new IntegerConfigKey( "forward.retry.delay", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG), + 100); /** * Position forwarding retry maximum retries. @@ -753,7 +746,8 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_COUNT = new IntegerConfigKey( "forward.retry.count", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG), + 10); /** * Position forwarding retry pending positions limit. @@ -761,7 +755,8 @@ public final class Keys { */ public static final ConfigKey FORWARD_RETRY_LIMIT = new IntegerConfigKey( "forward.retry.limit", - List.of(KeyType.CONFIG)); + List.of(KeyType.CONFIG), + 100); /** * Events forwarding URL. diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 7c82454b2..1eec7e097 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -129,7 +129,11 @@ public class NotificationManager { if (event.getMaintenanceId() != 0) { eventData.setMaintenance(cacheManager.getObject(Maintenance.class, event.getMaintenanceId())); } - eventForwarder.forward(eventData); + eventForwarder.forward(eventData, (success, throwable) -> { + if (!success) { + LOGGER.warn("Event forwarding failed", throwable); + } + }); } } diff --git a/src/main/java/org/traccar/forward/EventForwarder.java b/src/main/java/org/traccar/forward/EventForwarder.java index c3ad5efc0..1f991c0b5 100644 --- a/src/main/java/org/traccar/forward/EventForwarder.java +++ b/src/main/java/org/traccar/forward/EventForwarder.java @@ -16,5 +16,5 @@ package org.traccar.forward; public interface EventForwarder { - void forward(EventData eventData); + void forward(EventData eventData, ResultHandler resultHandler); } diff --git a/src/main/java/org/traccar/forward/EventForwarderJson.java b/src/main/java/org/traccar/forward/EventForwarderJson.java index c136fd4e2..7527d568a 100644 --- a/src/main/java/org/traccar/forward/EventForwarderJson.java +++ b/src/main/java/org/traccar/forward/EventForwarderJson.java @@ -15,33 +15,29 @@ */ package org.traccar.forward; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; -import javax.inject.Inject; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.client.InvocationCallback; +import javax.ws.rs.core.Response; public class EventForwarderJson implements EventForwarder { - private static final Logger LOGGER = LoggerFactory.getLogger(EventForwarderJson.class); - private final String url; private final String header; private final Client client; - @Inject public EventForwarderJson(Config config, Client client) { this.client = client; url = config.getString(Keys.EVENT_FORWARD_URL); header = config.getString(Keys.EVENT_FORWARD_HEADERS); } - public void forward(EventData eventData) { + @Override + public void forward(EventData eventData, ResultHandler resultHandler) { var requestBuilder = client.target(url).request(); if (header != null && !header.isEmpty()) { @@ -51,14 +47,20 @@ public class EventForwarderJson implements EventForwarder { } } - requestBuilder.async().post(Entity.json(eventData), new InvocationCallback<>() { + requestBuilder.async().post(Entity.json(eventData), new InvocationCallback() { @Override - public void completed(Object o) { + public void completed(Response response) { + if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) { + resultHandler.onResult(true, null); + } else { + int code = response.getStatusInfo().getStatusCode(); + resultHandler.onResult(false, new RuntimeException("HTTP code " + code)); + } } @Override public void failed(Throwable throwable) { - LOGGER.warn("Event forwarding failed", throwable); + resultHandler.onResult(false, throwable); } }); } diff --git a/src/main/java/org/traccar/forward/PositionData.java b/src/main/java/org/traccar/forward/PositionData.java new file mode 100644 index 000000000..784cf52f5 --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionData.java @@ -0,0 +1,45 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +import com.fasterxml.jackson.annotation.JsonInclude; +import org.traccar.model.Device; +import org.traccar.model.Position; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class PositionData { + + private Position position; + + public Position getPosition() { + return position; + } + + public void setPosition(Position position) { + this.position = position; + } + + private Device device; + + public Device getDevice() { + return device; + } + + public void setDevice(Device device) { + this.device = device; + } + +} diff --git a/src/main/java/org/traccar/forward/PositionForwarder.java b/src/main/java/org/traccar/forward/PositionForwarder.java new file mode 100644 index 000000000..58bd1dcc7 --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarder.java @@ -0,0 +1,20 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +public interface PositionForwarder { + void forward(PositionData positionData, ResultHandler resultHandler); +} diff --git a/src/main/java/org/traccar/forward/PositionForwarderJson.java b/src/main/java/org/traccar/forward/PositionForwarderJson.java new file mode 100644 index 000000000..27b96308e --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarderJson.java @@ -0,0 +1,86 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.InvocationCallback; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +public class PositionForwarderJson implements PositionForwarder { + + private final String url; + private final String header; + + private final Client client; + private final ObjectMapper objectMapper; + + public PositionForwarderJson(Config config, Client client, ObjectMapper objectMapper) { + this.client = client; + this.objectMapper = objectMapper; + this.url = config.getString(Keys.FORWARD_URL); + this.header = config.getString(Keys.FORWARD_HEADER); + } + + @Override + public void forward(PositionData positionData, ResultHandler resultHandler) { + var requestBuilder = client.target(url).request(); + + MediaType mediaType = MediaType.APPLICATION_JSON_TYPE; + if (header != null && !header.isEmpty()) { + for (String line: header.split("\\r?\\n")) { + String[] values = line.split(":", 2); + String headerName = values[0].trim(); + String headerValue = values[1].trim(); + if (headerName.equals(HttpHeaders.CONTENT_TYPE)) { + mediaType = MediaType.valueOf(headerValue); + } else { + requestBuilder.header(headerName, headerValue); + } + } + } + + try { + var entity = Entity.entity(objectMapper.writeValueAsString(positionData), mediaType); + requestBuilder.async().post(entity, new InvocationCallback() { + @Override + public void completed(Response response) { + if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) { + resultHandler.onResult(true, null); + } else { + int code = response.getStatusInfo().getStatusCode(); + resultHandler.onResult(false, new RuntimeException("HTTP code " + code)); + } + } + + @Override + public void failed(Throwable throwable) { + resultHandler.onResult(false, throwable); + } + }); + } catch (JsonProcessingException e) { + resultHandler.onResult(false, e); + } + } + +} diff --git a/src/main/java/org/traccar/forward/PositionForwarderUrl.java b/src/main/java/org/traccar/forward/PositionForwarderUrl.java new file mode 100644 index 000000000..53cc7ad24 --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarderUrl.java @@ -0,0 +1,166 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.helper.Checksum; +import org.traccar.model.Device; +import org.traccar.model.Position; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.InvocationCallback; +import javax.ws.rs.core.Response; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Calendar; +import java.util.Formatter; +import java.util.Locale; +import java.util.TimeZone; + +public class PositionForwarderUrl implements PositionForwarder { + + private final String url; + private final String header; + + private final Client client; + private final ObjectMapper objectMapper; + + public PositionForwarderUrl(Config config, Client client, ObjectMapper objectMapper) { + this.client = client; + this.objectMapper = objectMapper; + this.url = config.getString(Keys.FORWARD_URL); + this.header = config.getString(Keys.FORWARD_HEADER); + } + + @Override + public void forward(PositionData positionData, ResultHandler resultHandler) { + try { + String url = formatRequest(positionData); + var requestBuilder = client.target(url).request(); + + if (header != null && !header.isEmpty()) { + for (String line: header.split("\\r?\\n")) { + String[] values = line.split(":", 2); + String headerName = values[0].trim(); + String headerValue = values[1].trim(); + requestBuilder.header(headerName, headerValue); + } + } + + requestBuilder.async().get(new InvocationCallback() { + @Override + public void completed(Response response) { + if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) { + resultHandler.onResult(true, null); + } else { + int code = response.getStatusInfo().getStatusCode(); + resultHandler.onResult(false, new RuntimeException("HTTP code " + code)); + } + } + + @Override + public void failed(Throwable throwable) { + resultHandler.onResult(false, throwable); + } + }); + } catch (UnsupportedEncodingException | JsonProcessingException e) { + resultHandler.onResult(false, e); + } + } + + public String formatRequest( + PositionData positionData) throws UnsupportedEncodingException, JsonProcessingException { + + Position position = positionData.getPosition(); + Device device = positionData.getDevice(); + + String request = url + .replace("{name}", URLEncoder.encode(device.getName(), StandardCharsets.UTF_8)) + .replace("{uniqueId}", device.getUniqueId()) + .replace("{status}", device.getStatus()) + .replace("{deviceId}", String.valueOf(position.getDeviceId())) + .replace("{protocol}", String.valueOf(position.getProtocol())) + .replace("{deviceTime}", String.valueOf(position.getDeviceTime().getTime())) + .replace("{fixTime}", String.valueOf(position.getFixTime().getTime())) + .replace("{valid}", String.valueOf(position.getValid())) + .replace("{latitude}", String.valueOf(position.getLatitude())) + .replace("{longitude}", String.valueOf(position.getLongitude())) + .replace("{altitude}", String.valueOf(position.getAltitude())) + .replace("{speed}", String.valueOf(position.getSpeed())) + .replace("{course}", String.valueOf(position.getCourse())) + .replace("{accuracy}", String.valueOf(position.getAccuracy())) + .replace("{statusCode}", calculateStatus(position)); + + if (position.getAddress() != null) { + request = request.replace( + "{address}", URLEncoder.encode(position.getAddress(), StandardCharsets.UTF_8)); + } + + if (request.contains("{attributes}")) { + String attributes = objectMapper.writeValueAsString(position.getAttributes()); + request = request.replace( + "{attributes}", URLEncoder.encode(attributes, StandardCharsets.UTF_8)); + } + + if (request.contains("{gprmc}")) { + request = request.replace("{gprmc}", formatSentence(position)); + } + + return request; + } + + private static String formatSentence(Position position) { + + StringBuilder s = new StringBuilder("$GPRMC,"); + + try (Formatter f = new Formatter(s, Locale.ENGLISH)) { + + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ENGLISH); + calendar.setTimeInMillis(position.getFixTime().getTime()); + + f.format("%1$tH%1$tM%1$tS.%1$tL,A,", calendar); + + double lat = position.getLatitude(); + double lon = position.getLongitude(); + + f.format("%02d%07.4f,%c,", (int) Math.abs(lat), Math.abs(lat) % 1 * 60, lat < 0 ? 'S' : 'N'); + f.format("%03d%07.4f,%c,", (int) Math.abs(lon), Math.abs(lon) % 1 * 60, lon < 0 ? 'W' : 'E'); + + f.format("%.2f,%.2f,", position.getSpeed(), position.getCourse()); + f.format("%1$td%1$tm%1$ty,,", calendar); + } + + s.append(Checksum.nmea(s.substring(1))); + + return s.toString(); + } + + // OpenGTS status code + private String calculateStatus(Position position) { + if (position.hasAttribute(Position.KEY_ALARM)) { + return "0xF841"; // STATUS_PANIC_ON + } else if (position.getSpeed() < 1.0) { + return "0xF020"; // STATUS_LOCATION + } else { + return "0xF11C"; // STATUS_MOTION_MOVING + } + } + +} diff --git a/src/main/java/org/traccar/forward/ResultHandler.java b/src/main/java/org/traccar/forward/ResultHandler.java new file mode 100644 index 000000000..009daf495 --- /dev/null +++ b/src/main/java/org/traccar/forward/ResultHandler.java @@ -0,0 +1,20 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +public interface ResultHandler { + void onResult(boolean success, Throwable throwable); +} diff --git a/src/test/java/org/traccar/WebDataHandlerTest.java b/src/test/java/org/traccar/WebDataHandlerTest.java deleted file mode 100644 index 99dbb83fa..000000000 --- a/src/test/java/org/traccar/WebDataHandlerTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.traccar; - -import org.junit.Test; -import org.traccar.config.Config; -import org.traccar.config.Keys; -import org.traccar.model.Device; -import org.traccar.model.Position; -import org.traccar.session.cache.CacheManager; - -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class WebDataHandlerTest extends ProtocolTest { - - @Test - public void testFormatRequest() throws Exception { - - Config config = new Config(); - config.setString(Keys.FORWARD_URL, "http://localhost/?fixTime={fixTime}&gprmc={gprmc}&name={name}"); - - Position position = position("2016-01-01 01:02:03.000", true, 20, 30); - - var device = mock(Device.class); - when(device.getId()).thenReturn(1L); - when(device.getName()).thenReturn("test"); - when(device.getUniqueId()).thenReturn("123456789012345"); - when(device.getStatus()).thenReturn(Device.STATUS_ONLINE); - var cacheManager = mock(CacheManager.class); - when(cacheManager.getObject(eq(Device.class), anyLong())).thenReturn(device); - - WebDataHandler handler = new WebDataHandler(config, cacheManager, null, null, null); - - assertEquals( - "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", - handler.formatRequest(position)); - - } - -} diff --git a/src/test/java/org/traccar/forward/PositionForwarderUrlTest.java b/src/test/java/org/traccar/forward/PositionForwarderUrlTest.java new file mode 100644 index 000000000..522958052 --- /dev/null +++ b/src/test/java/org/traccar/forward/PositionForwarderUrlTest.java @@ -0,0 +1,42 @@ +package org.traccar.forward; + +import org.junit.Test; +import org.traccar.ProtocolTest; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.model.Device; +import org.traccar.model.Position; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class PositionForwarderUrlTest extends ProtocolTest { + + @Test + public void testFormatRequest() throws Exception { + + Config config = new Config(); + config.setString(Keys.FORWARD_URL, "http://localhost/?fixTime={fixTime}&gprmc={gprmc}&name={name}"); + + Position position = position("2016-01-01 01:02:03.000", true, 20, 30); + + var device = mock(Device.class); + when(device.getId()).thenReturn(1L); + when(device.getName()).thenReturn("test"); + when(device.getUniqueId()).thenReturn("123456789012345"); + when(device.getStatus()).thenReturn(Device.STATUS_ONLINE); + + PositionData positionData = new PositionData(); + positionData.setPosition(position); + positionData.setDevice(device); + + PositionForwarderUrl forwarder = new PositionForwarderUrl(config, null, null); + + assertEquals( + "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", + forwarder.formatRequest(positionData)); + + } + +} -- cgit v1.2.3 From 826c661819d044c8f1cf950795ee0f33cc7675c6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Nov 2022 16:44:15 -0800 Subject: Implement Kafka forwarding --- build.gradle | 1 + src/main/java/org/traccar/MainModule.java | 21 +++++--- src/main/java/org/traccar/config/Keys.java | 23 +++++--- .../org/traccar/forward/EventForwarderKafka.java | 61 ++++++++++++++++++++++ .../traccar/forward/PositionForwarderKafka.java | 55 +++++++++++++++++++ 5 files changed, 148 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/traccar/forward/EventForwarderKafka.java create mode 100644 src/main/java/org/traccar/forward/PositionForwarderKafka.java diff --git a/build.gradle b/build.gradle index 0e7d77bce..a5daf5924 100644 --- a/build.gradle +++ b/build.gradle @@ -83,6 +83,7 @@ dependencies { implementation "com.sun.xml.bind:jaxb-impl:3.0.2" // needs upgrade implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.314" + implementation "org.apache.kafka:kafka-clients:3.3.1" implementation ("com.google.firebase:firebase-admin:9.0.0") { exclude group: 'com.google.cloud', module: 'google-cloud-firestore' } diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 9d450fef7..6e59527bc 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -37,8 +37,10 @@ import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.forward.EventForwarder; import org.traccar.forward.EventForwarderJson; +import org.traccar.forward.EventForwarderKafka; import org.traccar.forward.PositionForwarder; import org.traccar.forward.PositionForwarderJson; +import org.traccar.forward.PositionForwarderKafka; import org.traccar.forward.PositionForwarderUrl; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; @@ -314,9 +316,13 @@ public class MainModule extends AbstractModule { @Singleton @Provides - public static EventForwarder provideEventForwarder(Config config, Client client) { + public static EventForwarder provideEventForwarder(Config config, Client client, ObjectMapper objectMapper) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - return new EventForwarderJson(config, client); + if (config.getString(Keys.EVENT_FORWARD_TYPE).equals("kafka")) { + return new EventForwarderKafka(config, objectMapper); + } else { + return new EventForwarderJson(config, client); + } } return null; } @@ -325,10 +331,13 @@ public class MainModule extends AbstractModule { @Provides public static PositionForwarder providePositionForwarder(Config config, Client client, ObjectMapper objectMapper) { if (config.hasKey(Keys.FORWARD_URL)) { - if (config.getBoolean(Keys.FORWARD_JSON)) { - return new PositionForwarderJson(config, client, objectMapper); - } else { - return new PositionForwarderUrl(config, client, objectMapper); + switch (config.getString(Keys.FORWARD_TYPE)) { + case "json": + return new PositionForwarderJson(config, client, objectMapper); + case "kafka": + return new PositionForwarderKafka(config, objectMapper); + default: + return new PositionForwarderUrl(config, client, objectMapper); } } return null; diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index b60cd82a0..2224192d9 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -698,6 +698,14 @@ public final class Keys { List.of(KeyType.CONFIG), "max-age=3600,public"); + /** + * Position forwarding format. Available options are "url", "json" and "kafka". Default is "url". + */ + public static final ConfigKey FORWARD_TYPE = new StringConfigKey( + "forward.type", + List.of(KeyType.CONFIG), + "url"); + /** * URL to forward positions. Data is passed through URL parameters. For example, {uniqueId} for device identifier, * {latitude} and {longitude} for coordinates. @@ -713,13 +721,6 @@ public final class Keys { "forward.header", List.of(KeyType.CONFIG)); - /** - * Boolean value to enable forwarding in JSON format. - */ - public static final ConfigKey FORWARD_JSON = new BooleanConfigKey( - "forward.json", - List.of(KeyType.CONFIG)); - /** * Position forwarding retrying enable. When enabled, additional attempts are made to deliver positions. If initial * delivery fails, because of an unreachable server or an HTTP response different from '2xx', the software waits @@ -758,6 +759,14 @@ public final class Keys { List.of(KeyType.CONFIG), 100); + /** + * Events forwarding format. Available options are "json" and "kafka". Default is "json". + */ + public static final ConfigKey EVENT_FORWARD_TYPE = new StringConfigKey( + "event.forward.type", + List.of(KeyType.CONFIG), + "json"); + /** * Events forwarding URL. */ diff --git a/src/main/java/org/traccar/forward/EventForwarderKafka.java b/src/main/java/org/traccar/forward/EventForwarderKafka.java new file mode 100644 index 000000000..71e06ddd1 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventForwarderKafka.java @@ -0,0 +1,61 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import java.util.Properties; + +public class EventForwarderKafka implements EventForwarder { + + private final Producer producer; + private final ObjectMapper objectMapper; + + public EventForwarderKafka(Config config, ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + Properties properties = new Properties(); + properties.put("bootstrap.servers", config.getString(Keys.EVENT_FORWARD_URL)); + properties.put("acks", "all"); + properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + producer = new KafkaProducer<>(properties); + } + + @SuppressWarnings("deprecation") + @Override + protected void finalize() { + producer.close(); + } + + @Override + public void forward(EventData eventData, ResultHandler resultHandler) { + try { + String key = Long.toString(eventData.getDevice().getId()); + String value = objectMapper.writeValueAsString(eventData); + producer.send(new ProducerRecord<>("events", key, value)); + resultHandler.onResult(true, null); + } catch (JsonProcessingException e) { + resultHandler.onResult(false, e); + } + } + +} diff --git a/src/main/java/org/traccar/forward/PositionForwarderKafka.java b/src/main/java/org/traccar/forward/PositionForwarderKafka.java new file mode 100644 index 000000000..3921539ac --- /dev/null +++ b/src/main/java/org/traccar/forward/PositionForwarderKafka.java @@ -0,0 +1,55 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import java.util.Properties; + +public class PositionForwarderKafka implements PositionForwarder { + + private final Producer producer; + private final ObjectMapper objectMapper; + + public PositionForwarderKafka(Config config, ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + Properties properties = new Properties(); + properties.put("bootstrap.servers", config.getString(Keys.EVENT_FORWARD_URL)); + properties.put("acks", "all"); + properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + producer = new KafkaProducer<>(properties); + } + + @Override + public void forward(PositionData positionData, ResultHandler resultHandler) { + try { + String key = Long.toString(positionData.getDevice().getId()); + String value = objectMapper.writeValueAsString(positionData); + producer.send(new ProducerRecord<>("positions", key, value)); + resultHandler.onResult(true, null); + } catch (JsonProcessingException e) { + resultHandler.onResult(false, e); + } + } + +} -- cgit v1.2.3 From 77c1e617587947c431b77773f53da5e222f4dd61 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 14 Nov 2022 08:19:22 -0800 Subject: Customizable Kafka topic --- src/main/java/org/traccar/config/Keys.java | 16 ++++++++++++++++ .../java/org/traccar/forward/EventForwarderKafka.java | 5 ++++- .../java/org/traccar/forward/PositionForwarderKafka.java | 7 +++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 2224192d9..9ae71921e 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -706,6 +706,14 @@ public final class Keys { List.of(KeyType.CONFIG), "url"); + /** + * Position forwarding Kafka topic. + */ + public static final ConfigKey FORWARD_TOPIC = new StringConfigKey( + "forward.topic", + List.of(KeyType.CONFIG), + "positions"); + /** * URL to forward positions. Data is passed through URL parameters. For example, {uniqueId} for device identifier, * {latitude} and {longitude} for coordinates. @@ -767,6 +775,14 @@ public final class Keys { List.of(KeyType.CONFIG), "json"); + /** + * Events forwarding Kafka topic. + */ + public static final ConfigKey EVENT_FORWARD_TOPIC = new StringConfigKey( + "event.forward.topic", + List.of(KeyType.CONFIG), + "events"); + /** * Events forwarding URL. */ diff --git a/src/main/java/org/traccar/forward/EventForwarderKafka.java b/src/main/java/org/traccar/forward/EventForwarderKafka.java index 71e06ddd1..db97d22de 100644 --- a/src/main/java/org/traccar/forward/EventForwarderKafka.java +++ b/src/main/java/org/traccar/forward/EventForwarderKafka.java @@ -30,6 +30,8 @@ public class EventForwarderKafka implements EventForwarder { private final Producer producer; private final ObjectMapper objectMapper; + private final String topic; + public EventForwarderKafka(Config config, ObjectMapper objectMapper) { this.objectMapper = objectMapper; Properties properties = new Properties(); @@ -38,6 +40,7 @@ public class EventForwarderKafka implements EventForwarder { properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); producer = new KafkaProducer<>(properties); + topic = config.getString(Keys.EVENT_FORWARD_TOPIC); } @SuppressWarnings("deprecation") @@ -51,7 +54,7 @@ public class EventForwarderKafka implements EventForwarder { try { String key = Long.toString(eventData.getDevice().getId()); String value = objectMapper.writeValueAsString(eventData); - producer.send(new ProducerRecord<>("events", key, value)); + producer.send(new ProducerRecord<>(topic, key, value)); resultHandler.onResult(true, null); } catch (JsonProcessingException e) { resultHandler.onResult(false, e); diff --git a/src/main/java/org/traccar/forward/PositionForwarderKafka.java b/src/main/java/org/traccar/forward/PositionForwarderKafka.java index 3921539ac..7432e9364 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderKafka.java +++ b/src/main/java/org/traccar/forward/PositionForwarderKafka.java @@ -30,14 +30,17 @@ public class PositionForwarderKafka implements PositionForwarder { private final Producer producer; private final ObjectMapper objectMapper; + private final String topic; + public PositionForwarderKafka(Config config, ObjectMapper objectMapper) { this.objectMapper = objectMapper; Properties properties = new Properties(); - properties.put("bootstrap.servers", config.getString(Keys.EVENT_FORWARD_URL)); + properties.put("bootstrap.servers", config.getString(Keys.FORWARD_URL)); properties.put("acks", "all"); properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); producer = new KafkaProducer<>(properties); + topic = config.getString(Keys.FORWARD_TOPIC); } @Override @@ -45,7 +48,7 @@ public class PositionForwarderKafka implements PositionForwarder { try { String key = Long.toString(positionData.getDevice().getId()); String value = objectMapper.writeValueAsString(positionData); - producer.send(new ProducerRecord<>("positions", key, value)); + producer.send(new ProducerRecord<>(topic, key, value)); resultHandler.onResult(true, null); } catch (JsonProcessingException e) { resultHandler.onResult(false, e); -- cgit v1.2.3 From 4c973263a82d7c3515a8054a24e3396dfcab0e93 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 16 Nov 2022 06:54:30 -0800 Subject: Fix missing device --- src/main/java/org/traccar/database/NotificationManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/traccar/database/NotificationManager.java b/src/main/java/org/traccar/database/NotificationManager.java index 1eec7e097..cb971b082 100644 --- a/src/main/java/org/traccar/database/NotificationManager.java +++ b/src/main/java/org/traccar/database/NotificationManager.java @@ -24,6 +24,7 @@ import org.traccar.forward.EventData; import org.traccar.forward.EventForwarder; import org.traccar.geocoder.Geocoder; import org.traccar.model.Calendar; +import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Maintenance; @@ -123,6 +124,7 @@ public class NotificationManager { EventData eventData = new EventData(); eventData.setEvent(event); eventData.setPosition(position); + eventData.setDevice(cacheManager.getObject(Device.class, event.getDeviceId())); if (event.getGeofenceId() != 0) { eventData.setGeofence(cacheManager.getObject(Geofence.class, event.getGeofenceId())); } -- cgit v1.2.3 From 63cab28f909343476ffa39983da533e169f02838 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 22 Nov 2022 07:30:09 -0800 Subject: Fix steps decoding --- src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index f0ae28756..eb5e16de2 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -266,8 +266,8 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { hasLocation = true; break; case 0x30: - buf.readUnsignedInt(); // timestamp - position.set(Position.KEY_STEPS, buf.readUnsignedInt()); + buf.readUnsignedIntLE(); // timestamp + position.set(Position.KEY_STEPS, buf.readUnsignedIntLE()); break; case 0x31: int i = 1; -- cgit v1.2.3 From 39e12dfb5a9fe13d93c89a078f2dd0c03a55b404 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 23 Nov 2022 19:00:05 -0800 Subject: Add TT18 4G test case --- src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java index 72f5dadd8..4a861fb06 100644 --- a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TzoneProtocolDecoderTest extends ProtocolTest { var decoder = inject(new TzoneProtocolDecoder(null)); + verifyAttributes(decoder, binary( + "545a003724240407020200000180322000001610160b151019100000000c010a07320101088600007dca000baa102837016a0114025500000169e80d0a")); + verifyAttributes(decoder, binary( "545a004d24240407010d0000018032100000031515090c052c2100000022030a033400201347000056860a03340020134700002feb0a03340020134700007d96000baa10211f01810127022d000001ebe00d0a")); -- cgit v1.2.3 From 19d10da19db57b2119c295cb452a271c3de48f85 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 24 Nov 2022 11:06:04 -0800 Subject: ATrack AK11 text responses --- .../org/traccar/protocol/AtrackProtocolDecoder.java | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 4567582db..340641729 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -100,7 +100,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { this.form = form; } - private static void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) { if (channel != null) { ByteBuf response = Unpooled.buffer(12); response.writeShort(0xfe02); @@ -526,20 +526,24 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { private List decodeText(Channel channel, SocketAddress remoteAddress, String sentence) { - int startIndex = -1; - for (int i = 0; i < 4; i++) { - startIndex = sentence.indexOf(',', startIndex + 1); + int positionIndex = -1; + for (int i = 0; i < 5; i++) { + positionIndex = sentence.indexOf(',', positionIndex + 1); } - int endIndex = sentence.indexOf(',', startIndex + 1); - String imei = sentence.substring(startIndex + 1, endIndex); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + String[] headers = sentence.substring(0, positionIndex).split(","); + long id = Long.parseLong(headers[2]); + int index = Integer.parseInt(headers[3]); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, headers[4]); if (deviceSession == null) { return null; } + sendResponse(channel, remoteAddress, id, index); + List positions = new LinkedList<>(); - String[] lines = sentence.substring(endIndex + 1).split("\r\n"); + String[] lines = sentence.substring(positionIndex + 1).split("\r\n"); for (String line : lines) { Position position = decodeTextLine(deviceSession, line); -- cgit v1.2.3 From 146de22b51139edcc3132f403e86006ac1fc3419 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 10:31:12 -0800 Subject: Support GL600 GPS lock --- src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java index 9fa550ded..9ed44f565 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 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,7 +143,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { boolean responseRequired = false; - while (buf.readableBytes() > 1) { + while (buf.readableBytes() >= 17) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 98c587a81..fc52e32e3 100644 --- a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Jt600ProtocolDecoder(null)); + verifyPositions(decoder, binary( + "2480433966040111002718031919195822424550114158888E15A40000F124080000000000F00F110A24991900000DF0C7")); + verifyPosition(decoder, buffer( "(8000632862,P45,290322,132412,25.28217,S,57.54683,W,A,0,0,5,0,0000000000,0,0,9,0)")); -- cgit v1.2.3 From 20ca33bf17c30bf2335d85365a224bc437e0347b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 11:14:15 -0800 Subject: Unknown device throttling --- src/main/java/org/traccar/config/Keys.java | 9 ++++- .../org/traccar/database/DeviceLookupService.java | 47 ++++++++++++++-------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 9ae71921e..09662fc85 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -452,7 +452,14 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * By default server syncs with the database if it encounters and unknown device. This flag allows to disable that + * Throttle unknown device database queries when it sends repeated requests. + */ + public static final ConfigKey DATABASE_THROTTLE_UNKNOWN = new BooleanConfigKey( + "database.throttleUnknown", + List.of(KeyType.CONFIG)); + + /** + * By default, server syncs with the database if it encounters and unknown device. This flag allows to disable that * behavior to improve performance in some cases. */ public static final ConfigKey DATABASE_IGNORE_UNKNOWN = new BooleanConfigKey( diff --git a/src/main/java/org/traccar/database/DeviceLookupService.java b/src/main/java/org/traccar/database/DeviceLookupService.java index 28910c24a..583b2ae35 100644 --- a/src/main/java/org/traccar/database/DeviceLookupService.java +++ b/src/main/java/org/traccar/database/DeviceLookupService.java @@ -20,6 +20,8 @@ import io.netty.util.Timer; import io.netty.util.TimerTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.model.Device; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -45,6 +47,8 @@ public class DeviceLookupService { private final Storage storage; private final Timer timer; + private final boolean throttlingEnabled; + private static class IdentifierInfo { private long lastQuery; private long delay; @@ -70,36 +74,45 @@ public class DeviceLookupService { private final Map identifierMap = new ConcurrentHashMap<>(); @Inject - public DeviceLookupService(Storage storage, Timer timer) { + public DeviceLookupService(Config config, Storage storage, Timer timer) { this.storage = storage; this.timer = timer; + throttlingEnabled = config.getBoolean(Keys.DATABASE_THROTTLE_UNKNOWN); } private synchronized boolean isThrottled(String uniqueId) { - IdentifierInfo info = identifierMap.get(uniqueId); - return info != null && System.currentTimeMillis() < info.lastQuery + info.delay; + if (throttlingEnabled) { + IdentifierInfo info = identifierMap.get(uniqueId); + return info != null && System.currentTimeMillis() < info.lastQuery + info.delay; + } else { + return false; + } } private synchronized void lookupSucceeded(String uniqueId) { - IdentifierInfo info = identifierMap.remove(uniqueId); - if (info != null) { - info.timeout.cancel(); + if (throttlingEnabled) { + IdentifierInfo info = identifierMap.remove(uniqueId); + if (info != null) { + info.timeout.cancel(); + } } } private synchronized void lookupFailed(String uniqueId) { - IdentifierInfo info = identifierMap.get(uniqueId); - if (info != null) { - info.timeout.cancel(); - info.delay = Math.min(info.delay * 2, THROTTLE_MAX_MS); - } else { - info = new IdentifierInfo(); - identifierMap.put(uniqueId, info); - info.delay = THROTTLE_MIN_MS; + if (throttlingEnabled) { + IdentifierInfo info = identifierMap.get(uniqueId); + if (info != null) { + info.timeout.cancel(); + info.delay = Math.min(info.delay * 2, THROTTLE_MAX_MS); + } else { + info = new IdentifierInfo(); + identifierMap.put(uniqueId, info); + info.delay = THROTTLE_MIN_MS; + } + info.lastQuery = System.currentTimeMillis(); + info.timeout = timer.newTimeout(new IdentifierTask(uniqueId), INFO_TIMEOUT_MS, TimeUnit.MILLISECONDS); + LOGGER.debug("Device lookup {} throttled for {} ms", uniqueId, info.delay); } - info.lastQuery = System.currentTimeMillis(); - info.timeout = timer.newTimeout(new IdentifierTask(uniqueId), INFO_TIMEOUT_MS, TimeUnit.MILLISECONDS); - LOGGER.debug("Device lookup {} throttled for {} ms", uniqueId, info.delay); } public Device lookup(String[] uniqueIds) { -- cgit v1.2.3 From 82cd47bf236808d4ef13b5c654ed5b52ed2746bb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 15:32:12 -0800 Subject: Update java versions --- build.gradle | 24 +++++++++++----------- .../java/org/traccar/storage/DatabaseModule.java | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/build.gradle b/build.gradle index a5daf5924..3dcef5a8d 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ ext { jettyVersion = "10.0.12" // jetty 11 javax to jakarta jerseyVersion = "2.37" // jersey 3 javax to jakarta jacksonVersion = "2.13.4" // same version as jersey-media-json-jackson dependency - protobufVersion = "3.21.7" + protobufVersion = "3.21.9" } sourceCompatibility = "11" @@ -42,16 +42,16 @@ enforce { dependencies { implementation "commons-codec:commons-codec:1.15" implementation "com.h2database:h2:2.1.214" - implementation "mysql:mysql-connector-java:8.0.30" - implementation "org.postgresql:postgresql:42.5.0" + implementation "com.mysql:mysql-connector-j:8.0.31" + implementation "org.postgresql:postgresql:42.5.1" implementation "com.microsoft.sqlserver:mssql-jdbc:11.2.1.jre11" implementation "com.zaxxer:HikariCP:5.0.1" - implementation "io.netty:netty-all:4.1.82.Final" - implementation "org.slf4j:slf4j-jdk14:2.0.3" + implementation "io.netty:netty-all:4.1.85.Final" + implementation "org.slf4j:slf4j-jdk14:2.0.5" implementation "com.google.inject:guice:$guiceVersion" implementation "com.google.inject.extensions:guice-servlet:$guiceVersion" implementation "org.owasp.encoder:encoder:1.2.3" - implementation "org.glassfish:javax.json:1.1.4" + implementation "org.glassfish:jakarta.json:1.1.6" implementation "org.eclipse.jetty:jetty-server:$jettyVersion" implementation "org.eclipse.jetty:jetty-servlet:$jettyVersion" implementation "org.eclipse.jetty:jetty-servlets:$jettyVersion" @@ -65,26 +65,26 @@ dependencies { implementation "org.glassfish.hk2:guice-bridge:2.6.1" // same version as jersey-hk2 implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr353:$jacksonVersion" - implementation "org.liquibase:liquibase-core:4.16.1" - implementation "com.sun.mail:javax.mail:1.6.2" + implementation "org.liquibase:liquibase-core:4.17.2" + implementation "com.sun.mail:jakarta.mail:1.6.7" implementation "org.jxls:jxls:2.4.7" // needs upgrade (wait for jexl 4) implementation "org.jxls:jxls-poi:1.0.16" // needs upgrade (wait for jexl 4) implementation "org.apache.velocity:velocity:1.7" // needs upgrade implementation "org.apache.velocity:velocity-tools:2.0" // needs upgrade implementation "org.apache.commons:commons-collections4:4.4" - implementation "org.mnode.ical4j:ical4j:3.2.5" + implementation "org.mnode.ical4j:ical4j:3.2.7" implementation "org.locationtech.spatial4j:spatial4j:0.8" implementation "org.locationtech.jts:jts-core:1.19.0" implementation "net.java.dev.jna:jna-platform:5.12.1" - implementation "com.github.jnr:jnr-posix:3.1.15" + implementation "com.github.jnr:jnr-posix:3.1.16" implementation "com.google.protobuf:protobuf-java:$protobufVersion" implementation "javax.xml.bind:jaxb-api:2.3.1" implementation "com.sun.xml.bind:jaxb-core:3.0.2" // needs upgrade implementation "com.sun.xml.bind:jaxb-impl:3.0.2" // needs upgrade implementation "javax.activation:activation:1.1.1" - implementation "com.amazonaws:aws-java-sdk-sns:1.12.314" + implementation "com.amazonaws:aws-java-sdk-sns:1.12.349" implementation "org.apache.kafka:kafka-clients:3.3.1" - implementation ("com.google.firebase:firebase-admin:9.0.0") { + implementation ("com.google.firebase:firebase-admin:9.1.1") { exclude group: 'com.google.cloud', module: 'google-cloud-firestore' } testImplementation "junit:junit:4.13.2" diff --git a/src/main/java/org/traccar/storage/DatabaseModule.java b/src/main/java/org/traccar/storage/DatabaseModule.java index 71bf84b34..3e3483818 100644 --- a/src/main/java/org/traccar/storage/DatabaseModule.java +++ b/src/main/java/org/traccar/storage/DatabaseModule.java @@ -24,7 +24,7 @@ import liquibase.Liquibase; import liquibase.database.Database; import liquibase.database.DatabaseFactory; import liquibase.exception.LiquibaseException; -import liquibase.resource.FileSystemResourceAccessor; +import liquibase.resource.DirectoryResourceAccessor; import liquibase.resource.ResourceAccessor; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -80,7 +80,7 @@ public class DatabaseModule extends AbstractModule { if (config.hasKey(Keys.DATABASE_CHANGELOG)) { - ResourceAccessor resourceAccessor = new FileSystemResourceAccessor(new File(".")); + ResourceAccessor resourceAccessor = new DirectoryResourceAccessor(new File(".")); Database database = DatabaseFactory.getInstance().openDatabase( config.getString(Keys.DATABASE_URL), -- cgit v1.2.3 From 1a08e7cc2612539e6e16bb17b76a8d6866bb24f7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 15:50:39 -0800 Subject: Update version number --- build.gradle | 2 +- setup/traccar.iss | 2 +- swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 3dcef5a8d..aa4ff41cd 100644 --- a/build.gradle +++ b/build.gradle @@ -101,7 +101,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.4", + "Implementation-Version": "5.5", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/traccar.iss b/setup/traccar.iss index 66d2bd401..28b33adfb 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.4 +AppVersion=5.5 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/swagger.json b/swagger.json index 825e0d003..3eab9b522 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.4", + "version": "5.5", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", -- cgit v1.2.3 From 938872ff5e2fad867720ec9c971ea432ba623c2c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 16:17:00 -0800 Subject: Update python version --- tools/test-commands.py | 2 +- tools/test-generator.py | 2 +- tools/test-integration.py | 2 +- tools/test-map.py | 2 +- tools/test-performance.py | 2 +- tools/test-trips.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/test-commands.py b/tools/test-commands.py index 040efb177..6e310051a 100755 --- a/tools/test-commands.py +++ b/tools/test-commands.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 import socket import binascii diff --git a/tools/test-generator.py b/tools/test-generator.py index d49b98744..6e30c7fea 100755 --- a/tools/test-generator.py +++ b/tools/test-generator.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 import sys import math diff --git a/tools/test-integration.py b/tools/test-integration.py index 34f81ee83..f926a8ae9 100755 --- a/tools/test-integration.py +++ b/tools/test-integration.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 import sys import os diff --git a/tools/test-map.py b/tools/test-map.py index ab4466b09..5808c1fbb 100755 --- a/tools/test-map.py +++ b/tools/test-map.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 import urllib import urllib2 diff --git a/tools/test-performance.py b/tools/test-performance.py index ec31e9b86..a2dd6e66d 100755 --- a/tools/test-performance.py +++ b/tools/test-performance.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 import asyncio import random diff --git a/tools/test-trips.py b/tools/test-trips.py index a71357fdb..267752fbb 100755 --- a/tools/test-trips.py +++ b/tools/test-trips.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 import urllib import httplib -- cgit v1.2.3 From 6142cf557dc130828c12dbfb25ab18eda4bc0f7d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 16:19:49 -0800 Subject: Update python scripts --- tools/test-generator.py | 4 ++-- tools/test-integration.py | 4 ++-- tools/test-map.py | 6 +++--- tools/test-trips.py | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/test-generator.py b/tools/test-generator.py index 6e30c7fea..ed135b4aa 100755 --- a/tools/test-generator.py +++ b/tools/test-generator.py @@ -3,7 +3,7 @@ import sys import math import urllib -import httplib +import http.client as httplib import time import random @@ -51,7 +51,7 @@ def send(conn, lat, lon, altitude, course, speed, battery, alarm, ignition, accu params = params + (('fuel', fuel),) if driverUniqueId: params = params + (('driverUniqueId', driverUniqueId),) - conn.request('GET', '?' + urllib.urlencode(params)) + conn.request('GET', '?' + urllib.parse.urlencode(params)) conn.getresponse().read() def course(lat1, lon1, lat2, lon2): diff --git a/tools/test-integration.py b/tools/test-integration.py index f926a8ae9..89f1c76ed 100755 --- a/tools/test-integration.py +++ b/tools/test-integration.py @@ -140,7 +140,7 @@ def load_ports(): def login(): request = urllib2.Request(baseUrl + '/api/session') - response = urllib2.urlopen(request, urllib.urlencode(user)) + response = urllib2.urlopen(request, urllib.parse.urlencode(user)) if debug: print '\nlogin: %s\n' % repr(json.load(response)) return response.headers.get('Set-Cookie') @@ -176,7 +176,7 @@ def send_message(port, message): def get_protocols(cookie, device_id): params = { 'deviceId' : device_id, 'from' : '2000-01-01T00:00:00.000Z', 'to' : '2050-01-01T00:00:00.000Z' } - request = urllib2.Request(baseUrl + '/api/positions?' + urllib.urlencode(params)) + request = urllib2.Request(baseUrl + '/api/positions?' + urllib.parse.urlencode(params)) request.add_header('Cookie', cookie) request.add_header('Content-Type', 'application/json') request.add_header('Accept', 'application/json') diff --git a/tools/test-map.py b/tools/test-map.py index 5808c1fbb..362c95878 100755 --- a/tools/test-map.py +++ b/tools/test-map.py @@ -2,7 +2,7 @@ import urllib import urllib2 -import httplib +import http.client as httplib import time import random import json @@ -14,7 +14,7 @@ devices = 500 def login(): request = urllib2.Request(baseUrl + '/api/session') - response = urllib2.urlopen(request, urllib.urlencode(user)) + response = urllib2.urlopen(request, urllib.parse.urlencode(user)) return response.headers.get('Set-Cookie') def add_device(cookie, unique_id): @@ -29,7 +29,7 @@ def add_device(cookie, unique_id): def send_message(conn, device_id): params = (('id', device_id), ('lat', random.uniform(59, 61)), ('lon', random.uniform(29, 31))) - conn.request('GET', '?' + urllib.urlencode(params)) + conn.request('GET', '?' + urllib.parse.urlencode(params)) conn.getresponse().read() cookie = login() diff --git a/tools/test-trips.py b/tools/test-trips.py index 267752fbb..3c994fd83 100755 --- a/tools/test-trips.py +++ b/tools/test-trips.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import urllib -import httplib +import http.client as httplib import time import datetime @@ -25,7 +25,7 @@ points = [ def send(conn, time, lat, lon, speed): params = (('id', id), ('timestamp', int(time)), ('lat', lat), ('lon', lon), ('speed', speed)) - conn.request('POST', '?' + urllib.urlencode(params)) + conn.request('POST', '?' + urllib.parse.urlencode(params)) conn.getresponse().read() conn = httplib.HTTPConnection(server) -- cgit v1.2.3 From dbadcca56972dee45d2c39c94b088e194a240c09 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 16:35:59 -0800 Subject: Update submodule --- traccar-web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traccar-web b/traccar-web index 033c88d5d..610ce1e54 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit 033c88d5d4092f9daca90a3ef984deacd593a29e +Subproject commit 610ce1e5447d47c316f87887b64c4c459bad8559 -- cgit v1.2.3 From 9be95552c1914630a6a4936686887d201d8f2a60 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 17:22:03 -0800 Subject: Update gradle file --- build.gradle | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index aa4ff41cd..297063ce2 100644 --- a/build.gradle +++ b/build.gradle @@ -84,9 +84,7 @@ dependencies { implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.349" implementation "org.apache.kafka:kafka-clients:3.3.1" - implementation ("com.google.firebase:firebase-admin:9.1.1") { - exclude group: 'com.google.cloud', module: 'google-cloud-firestore' - } + implementation "com.google.firebase:firebase-admin:9.1.1" testImplementation "junit:junit:4.13.2" testImplementation "org.mockito:mockito-core:4.+" } -- cgit v1.2.3 From 36579b977f34dd5393aef19b63160fb1ffba09f4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 2 Dec 2022 16:38:38 -0800 Subject: Fix DualCam init response --- src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index e646c4e4a..d03f7648d 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -84,7 +84,7 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { response.writeShort(file.length()); response.writeCharSequence(file, StandardCharsets.US_ASCII); } else { - response.writeShort(MSG_COMPLETE); + response.writeShort(MSG_INIT); } channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } -- cgit v1.2.3 From 2fcd5c8decf9f329c3e2325ce950d2b0493b29ab Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 2 Dec 2022 17:22:46 -0800 Subject: Decode Cellocator CR300 reason --- src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java index ecd09a2d8..07f7f1692 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@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,7 +119,7 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_STATUS, buf.readUnsignedByte() & 0x0f); buf.readUnsignedByte(); // operator / configuration flags - buf.readUnsignedByte(); // reason data + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("mode", buf.readUnsignedByte()); -- cgit v1.2.3 From b2f021bc447884d85c9fbcce93bb708d3702d1d8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 4 Dec 2022 10:38:38 -0800 Subject: Improve permissions check --- .../traccar/api/security/PermissionsService.java | 32 ++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index 37bb6fd72..4421572d7 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -120,25 +120,35 @@ public class PermissionsService { } } - public void checkEdit(long userId, Object object, boolean addition) throws StorageException, SecurityException { + public void checkEdit(long userId, BaseModel object, boolean addition) throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { checkEdit(userId, object.getClass(), addition); - boolean denied = false; if (object instanceof GroupedModel) { - long groupId = ((GroupedModel) object).getGroupId(); - if (groupId > 0) { - checkPermission(Group.class, userId, groupId); + GroupedModel after = ((GroupedModel) object); + if (after.getGroupId() > 0) { + GroupedModel before = null; + if (!addition) { + before = storage.getObject(after.getClass(), new Request( + new Columns.Include("groupId"), new Condition.Equals("id", object.getId()))); + } + if (before == null || before.getGroupId() != after.getGroupId()) { + checkPermission(Group.class, userId, after.getGroupId()); + } } } if (object instanceof ScheduledModel) { - long calendarId = ((ScheduledModel) object).getCalendarId(); - if (calendarId > 0) { - denied = storage.getPermissions(User.class, userId, Calendar.class, calendarId).isEmpty(); + ScheduledModel after = ((ScheduledModel) object); + if (after.getCalendarId() > 0) { + ScheduledModel before = null; + if (!addition) { + before = storage.getObject(after.getClass(), new Request( + new Columns.Include("calendarId"), new Condition.Equals("id", object.getId()))); + } + if (before == null || before.getCalendarId() != after.getCalendarId()) { + checkPermission(Calendar.class, userId, after.getCalendarId()); + } } } - if (denied) { - throw new SecurityException("Write access denied"); - } } } -- cgit v1.2.3 From 95ee5109d56fdcb01bcf8f1f620d00654fafb4a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 6 Dec 2022 17:00:10 -0800 Subject: Fix DMT Bolt2 alarms --- src/main/java/org/traccar/protocol/DmtProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java index 0fd83f503..320aa1b60 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java @@ -184,9 +184,9 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); - if (!BitUtil.check(input, 1)) { + if (!BitUtil.check(status, 1)) { position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - } else if (BitUtil.check(input, 6)) { + } else if (BitUtil.check(status, 6)) { position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); } -- cgit v1.2.3 From 5e6761cf355110dc91b5bf7847f57570473a19b2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 8 Dec 2022 12:55:27 -0800 Subject: Fix Teltonika temperature (fix #4993) --- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index 89af20b22..c63d74c9c 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -234,10 +234,10 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(66, null, (p, b) -> p.set(Position.KEY_POWER, b.readUnsignedShort() * 0.001)); register(67, null, (p, b) -> p.set(Position.KEY_BATTERY, b.readUnsignedShort() * 0.001)); register(68, fmbXXX, (p, b) -> p.set("batteryCurrent", b.readUnsignedShort() * 0.001)); - register(72, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 1, b.readShort() * 0.1)); - register(73, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 2, b.readShort() * 0.1)); - register(74, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 3, b.readShort() * 0.1)); - register(75, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 4, b.readShort() * 0.1)); + register(72, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 1, b.readInt() * 0.1)); + register(73, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 2, b.readInt() * 0.1)); + register(74, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 3, b.readInt() * 0.1)); + register(75, fmbXXX, (p, b) -> p.set(Position.PREFIX_TEMP + 4, b.readInt() * 0.1)); register(78, null, (p, b) -> { long driverUniqueId = b.readLong(); if (driverUniqueId > 0) { -- cgit v1.2.3 From 4b9ff1bd206adb826262acd4e3daf5c962518d7c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 10 Dec 2022 09:27:17 -0800 Subject: Fix cache updates --- src/main/java/org/traccar/session/cache/CacheManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index dc7382223..9d2350012 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -227,6 +227,15 @@ public class CacheManager implements BroadcastInterface { broadcastService.invalidateObject(true, object.getClass(), object.getId()); } + if (object instanceof Server) { + invalidateServer(); + return; + } + if (object instanceof User) { + invalidateUsers(); + return; + } + boolean invalidate = false; var before = getObject(object.getClass(), object.getId()); if (before == null) { -- cgit v1.2.3 From 867e800009bf361c3da9306bc5a9e3f1fab43869 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 11 Dec 2022 09:10:11 -0800 Subject: Improve T55 IP identification --- src/main/java/org/traccar/protocol/T55ProtocolDecoder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 90382439e..51f06a801 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -379,11 +379,12 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { } deviceSession = getDeviceSession(channel, remoteAddress, id); sentence = sentence.substring(index); - } else if (remoteAddress instanceof InetSocketAddress) { - String host = ((InetSocketAddress) remoteAddress).getHostString(); - deviceSession = getDeviceSession(channel, remoteAddress, host); } else { deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null && remoteAddress instanceof InetSocketAddress) { + String host = ((InetSocketAddress) remoteAddress).getHostString(); + deviceSession = getDeviceSession(channel, remoteAddress, host); + } } if (sentence.startsWith("$PGID")) { -- cgit v1.2.3 From b274f55b7ba6128c714484460a81189105df516b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Dec 2022 11:31:49 -0800 Subject: Dedicated LocationIQ geocoder --- setup/default.xml | 3 +-- src/main/java/org/traccar/MainModule.java | 23 +++-------------- .../org/traccar/geocoder/LocationIqGeocoder.java | 29 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/traccar/geocoder/LocationIqGeocoder.java diff --git a/setup/default.xml b/setup/default.xml index 77561109c..c00d29384 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -16,8 +16,7 @@ false true - nominatim - https://us1.locationiq.com/v1/reverse.php + locationiq pk.689d849289c8c63708068b2ff1f63b2d true true diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 6e59527bc..f3d04f634 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -42,25 +42,7 @@ import org.traccar.forward.PositionForwarder; import org.traccar.forward.PositionForwarderJson; import org.traccar.forward.PositionForwarderKafka; import org.traccar.forward.PositionForwarderUrl; -import org.traccar.geocoder.AddressFormat; -import org.traccar.geocoder.BanGeocoder; -import org.traccar.geocoder.BingMapsGeocoder; -import org.traccar.geocoder.FactualGeocoder; -import org.traccar.geocoder.GeoapifyGeocoder; -import org.traccar.geocoder.GeocodeFarmGeocoder; -import org.traccar.geocoder.GeocodeXyzGeocoder; -import org.traccar.geocoder.Geocoder; -import org.traccar.geocoder.GisgraphyGeocoder; -import org.traccar.geocoder.GoogleGeocoder; -import org.traccar.geocoder.HereGeocoder; -import org.traccar.geocoder.MapQuestGeocoder; -import org.traccar.geocoder.MapTilerGeocoder; -import org.traccar.geocoder.MapboxGeocoder; -import org.traccar.geocoder.MapmyIndiaGeocoder; -import org.traccar.geocoder.NominatimGeocoder; -import org.traccar.geocoder.OpenCageGeocoder; -import org.traccar.geocoder.PositionStackGeocoder; -import org.traccar.geocoder.TomTomGeocoder; +import org.traccar.geocoder.*; import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; import org.traccar.geolocation.MozillaGeolocationProvider; @@ -183,6 +165,9 @@ public class MainModule extends AbstractModule { case "nominatim": geocoder = new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); break; + case "locationiq": + geocoder = new LocationIqGeocoder(client, url, key, language, cacheSize, addressFormat); + break; case "gisgraphy": geocoder = new GisgraphyGeocoder(client, url, cacheSize, addressFormat); break; diff --git a/src/main/java/org/traccar/geocoder/LocationIqGeocoder.java b/src/main/java/org/traccar/geocoder/LocationIqGeocoder.java new file mode 100644 index 000000000..f2ffe02d6 --- /dev/null +++ b/src/main/java/org/traccar/geocoder/LocationIqGeocoder.java @@ -0,0 +1,29 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.geocoder; + +import javax.ws.rs.client.Client; + +public class LocationIqGeocoder extends NominatimGeocoder { + + private static final String DEFAULT_URL = "https://us1.locationiq.com/v1/reverse.php"; + + public LocationIqGeocoder( + Client client, String url, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, url != null ? url : DEFAULT_URL, key, language, cacheSize, addressFormat); + } + +} -- cgit v1.2.3 From 1a39c3ed8ddf78acdc50e25aae76f647243f2a00 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Dec 2022 13:07:35 -0800 Subject: Fix imports --- src/main/java/org/traccar/MainModule.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index f3d04f634..a8f895d3b 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -42,7 +42,26 @@ import org.traccar.forward.PositionForwarder; import org.traccar.forward.PositionForwarderJson; import org.traccar.forward.PositionForwarderKafka; import org.traccar.forward.PositionForwarderUrl; -import org.traccar.geocoder.*; +import org.traccar.geocoder.AddressFormat; +import org.traccar.geocoder.BanGeocoder; +import org.traccar.geocoder.BingMapsGeocoder; +import org.traccar.geocoder.FactualGeocoder; +import org.traccar.geocoder.GeoapifyGeocoder; +import org.traccar.geocoder.GeocodeFarmGeocoder; +import org.traccar.geocoder.GeocodeXyzGeocoder; +import org.traccar.geocoder.Geocoder; +import org.traccar.geocoder.GisgraphyGeocoder; +import org.traccar.geocoder.GoogleGeocoder; +import org.traccar.geocoder.HereGeocoder; +import org.traccar.geocoder.LocationIqGeocoder; +import org.traccar.geocoder.MapQuestGeocoder; +import org.traccar.geocoder.MapTilerGeocoder; +import org.traccar.geocoder.MapboxGeocoder; +import org.traccar.geocoder.MapmyIndiaGeocoder; +import org.traccar.geocoder.NominatimGeocoder; +import org.traccar.geocoder.OpenCageGeocoder; +import org.traccar.geocoder.PositionStackGeocoder; +import org.traccar.geocoder.TomTomGeocoder; import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; import org.traccar.geolocation.MozillaGeolocationProvider; -- cgit v1.2.3 From a87c77da9e8d39856e2a16ae3d3aa385e068a1e8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 13 Dec 2022 07:35:58 -0800 Subject: Handle missing user id --- src/main/java/org/traccar/api/AsyncSocketServlet.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/api/AsyncSocketServlet.java b/src/main/java/org/traccar/api/AsyncSocketServlet.java index 40e1551a1..91a745eeb 100644 --- a/src/main/java/org/traccar/api/AsyncSocketServlet.java +++ b/src/main/java/org/traccar/api/AsyncSocketServlet.java @@ -51,11 +51,12 @@ public class AsyncSocketServlet extends JettyWebSocketServlet { factory.setIdleTimeout(Duration.ofMillis(config.getLong(Keys.WEB_TIMEOUT))); factory.setCreator((req, resp) -> { if (req.getSession() != null) { - long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); - return new AsyncSocket(objectMapper, connectionManager, storage, userId); - } else { - return null; + Long userId = (Long) ((HttpSession) req.getSession()).getAttribute(SessionResource.USER_ID_KEY); + if (userId != null) { + return new AsyncSocket(objectMapper, connectionManager, storage, userId); + } } + return null; }); } -- cgit v1.2.3 From 64391161c1fb03bd9ff5ea30749b4e00230fa8aa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Dec 2022 06:59:53 -0800 Subject: Handle Teltonika heartbeat --- src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java | 4 ++-- src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java | 8 +++++--- src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java | 2 +- .../java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java index c30fee6e3..3a0962584 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 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@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 TeltonikaFrameDecoder extends BaseFrameDecoder { ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception { while (buf.isReadable() && buf.getByte(buf.readerIndex()) == (byte) 0xff) { - buf.skipBytes(1); + return buf.readRetainedSlice(1); } if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) { diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index c63d74c9c..929eca8aa 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -647,9 +647,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private Object decodeTcp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private Object decodeTcp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - if (buf.getUnsignedShort(0) > 0) { + if (buf.readableBytes() == 1 && buf.readUnsignedByte() == 0xff) { + return null; + } else if (buf.getUnsignedShort(0) > 0) { parseIdentification(channel, remoteAddress, buf); } else { buf.skipBytes(4); @@ -659,7 +661,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { return null; } - private Object decodeUdp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + private Object decodeUdp(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { buf.readUnsignedShort(); // length buf.readUnsignedShort(); // packet id diff --git a/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java index d5c7fcdb0..adc768460 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java @@ -11,7 +11,7 @@ public class TeltonikaFrameDecoderTest extends ProtocolTest { var decoder = inject(new TeltonikaFrameDecoder()); verifyFrame( - binary("000F313233343536373839303132333435"), + binary("ff"), decoder.decode(null, null, binary("FF000F313233343536373839303132333435"))); verifyFrame( diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 188c4b6eb..ba64642f2 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -125,6 +125,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "000000000000004a08010000015ebc1da508002411926621f15246010b00b913005e000f06ef01f00150011505c800450108b5000bb6000642381b18005ecd0318ce19cd430f5844000001f1000061a900010000c8e1")); + verifyNull(decoder, binary( + "ff")); + decoder.setExtended(true); verifyPositions(decoder, false, binary( -- cgit v1.2.3 From 11f90f5b779e9af3a22907766254f3400ef8bc50 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Dec 2022 12:42:56 -0800 Subject: Fix recovery script --- tools/recover.py | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/tools/recover.py b/tools/recover.py index 01e01f92e..dfa94c978 100755 --- a/tools/recover.py +++ b/tools/recover.py @@ -1,35 +1,52 @@ -#!/usr/bin/python +#!/usr/bin/env python3 import sys import re +import os +import xml.etree.ElementTree import socket import binascii +import time if len(sys.argv) < 2: sys.exit("log file is not provided") path = sys.argv[1] -p = re.compile(r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} DEBUG: \[([0-9a-fA-F]{8}): (\d+) < [\d.]+] HEX: ([0-9a-fA-F]+)") +p = re.compile(r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} INFO: \[([TU][0-9a-fA-F]{8}): (\S+) < [\d.]+] ([0-9a-fA-F]+)") -ports = {} +def load_ports(): + ports = {} + dir = os.path.dirname(os.path.abspath(__file__)) + root = xml.etree.ElementTree.parse(dir + '/../setup/default.xml').getroot() + for entry in root.findall('entry'): + key = entry.attrib['key'] + if key.endswith('.port'): + ports[key[:-5]] = int(entry.text) + return ports + +ports = load_ports() +protocols = {} messages = {} for line in open(path): - if "HEX:" in line: - m = p.match(line) - if m: - session = m.group(1) - port = m.group(2) - message = m.group(3) - ports[session] = port - if session not in messages: - messages[session] = [] - messages[session].append(message) - -for session in ports: - port = ports[session] + print(line) + m = p.match(line) + if m: + session = m.group(1) + protocol = m.group(2) + message = m.group(3) + protocols[session] = protocol + if session not in messages: + messages[session] = [] + messages[session].append(message) + +print('Total: %d' % len(messages)) + +for session in protocols: + port = ports[protocols[session]] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("localhost", int(port))) for message in messages[session]: s.send(binascii.unhexlify(message)) + time.sleep(0.5) s.close() -- cgit v1.2.3 From 836dc4138fdcf560a31c6a90769b19f6a0d0e438 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Dec 2022 15:37:54 -0800 Subject: Add motion fluctuation test --- .../handler/events/MotionEventHandlerTest.java | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 22afbfa52..25c766b51 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -1,5 +1,6 @@ package org.traccar.handler.events; +import org.junit.Ignore; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.model.Event; @@ -61,6 +62,38 @@ public class MotionEventHandlerTest extends BaseTest { verifyState(state, false, 0); } + @Ignore + @Test + public void testMotionFluctuation() throws ParseException { + TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false, 0.01); + + MotionState state = new MotionState(); + + MotionProcessor.updateState(state, position("2017-01-01 00:00:00", false, 0, null), false, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, false, 0); + + MotionProcessor.updateState(state, position("2017-01-01 00:02:00", true, 100, null), true, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, true, 100); + + MotionProcessor.updateState(state, position("2017-01-01 00:02:00", true, 700, null), true, tripsConfig); + assertEquals(Event.TYPE_DEVICE_MOVING, state.getEvent().getType()); + verifyState(state, true, 0); + + MotionProcessor.updateState(state, position("2017-01-01 00:03:00", false, 700, null), false, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, false, 700); + + MotionProcessor.updateState(state, position("2017-01-01 00:04:00", true, 1000, null), true, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, true, 1000); + + MotionProcessor.updateState(state, position("2017-01-01 00:06:00", true, 2000, null), true, tripsConfig); + assertNull(state.getEvent()); + verifyState(state, true, 2000); + } + @Test public void testStopWithPositionIgnition() throws ParseException { TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, true, false, 0.01); -- cgit v1.2.3 From 3b36ac38a0c4e193ea8085eb5556dffd8205bb17 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Dec 2022 16:08:25 -0800 Subject: Handle motion fluctuation (fix #5000) --- schema/changelog-5.6.xml | 17 +++++++++++++++++ schema/changelog-master.xml | 1 + .../org/traccar/handler/events/MotionEventHandler.java | 2 +- src/main/java/org/traccar/model/Device.java | 13 +++++++++++++ .../java/org/traccar/reports/common/ReportUtils.java | 4 +++- .../java/org/traccar/session/state/MotionProcessor.java | 10 ++++++++-- .../java/org/traccar/session/state/MotionState.java | 13 +++++++++++++ .../traccar/handler/events/MotionEventHandlerTest.java | 7 +++---- tools/recover.py | 2 +- 9 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 schema/changelog-5.6.xml diff --git a/schema/changelog-5.6.xml b/schema/changelog-5.6.xml new file mode 100644 index 000000000..335f7b3a8 --- /dev/null +++ b/schema/changelog-5.6.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index cc39c5c41..0835918c9 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -36,5 +36,6 @@ + diff --git a/src/main/java/org/traccar/handler/events/MotionEventHandler.java b/src/main/java/org/traccar/handler/events/MotionEventHandler.java index 1b9763c41..c406bd935 100644 --- a/src/main/java/org/traccar/handler/events/MotionEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MotionEventHandler.java @@ -75,7 +75,7 @@ public class MotionEventHandler extends BaseEventHandler { state.toDevice(device); try { storage.updateObject(device, new Request( - new Columns.Include("motionState", "motionTime", "motionDistance"), + new Columns.Include("motionStreak", "motionState", "motionTime", "motionDistance"), new Condition.Equals("id", device.getId()))); } catch (StorageException e) { LOGGER.warn("Update device motion error", e); diff --git a/src/main/java/org/traccar/model/Device.java b/src/main/java/org/traccar/model/Device.java index 7728172cb..b8c87921d 100644 --- a/src/main/java/org/traccar/model/Device.java +++ b/src/main/java/org/traccar/model/Device.java @@ -162,6 +162,19 @@ public class Device extends GroupedModel implements Disableable { this.expirationTime = expirationTime; } + private boolean motionStreak; + + @QueryIgnore + @JsonIgnore + public boolean getMotionStreak() { + return motionStreak; + } + + @JsonIgnore + public void setMotionStreak(boolean motionStreak) { + this.motionStreak = motionStreak; + } + private boolean motionState; @QueryIgnore diff --git a/src/main/java/org/traccar/reports/common/ReportUtils.java b/src/main/java/org/traccar/reports/common/ReportUtils.java index 120dadcf5..a7c420095 100644 --- a/src/main/java/org/traccar/reports/common/ReportUtils.java +++ b/src/main/java/org/traccar/reports/common/ReportUtils.java @@ -354,7 +354,9 @@ public class ReportUtils { boolean trips = reportClass.equals(TripReportItem.class); MotionState motionState = new MotionState(); - motionState.setMotionState(isMoving(positions, 0, tripsConfig)); + boolean initialValue = isMoving(positions, 0, tripsConfig); + motionState.setMotionStreak(initialValue); + motionState.setMotionState(initialValue); boolean detected = trips == motionState.getMotionState(); int startEventIndex = detected ? 0 : -1; diff --git a/src/main/java/org/traccar/session/state/MotionProcessor.java b/src/main/java/org/traccar/session/state/MotionProcessor.java index b9d706492..a1737a739 100644 --- a/src/main/java/org/traccar/session/state/MotionProcessor.java +++ b/src/main/java/org/traccar/session/state/MotionProcessor.java @@ -59,6 +59,7 @@ public final class MotionProcessor { String eventType = newState ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; Event event = new Event(eventType, position); + state.setMotionStreak(newState); state.setMotionTime(null); state.setMotionDistance(0); state.setEvent(event); @@ -67,8 +68,13 @@ public final class MotionProcessor { } } else { state.setMotionState(newState); - state.setMotionTime(position.getFixTime()); - state.setMotionDistance(position.getDouble(Position.KEY_TOTAL_DISTANCE)); + if (state.getMotionStreak() == newState) { + state.setMotionTime(null); + state.setMotionDistance(0); + } else { + state.setMotionTime(position.getFixTime()); + state.setMotionDistance(position.getDouble(Position.KEY_TOTAL_DISTANCE)); + } } } diff --git a/src/main/java/org/traccar/session/state/MotionState.java b/src/main/java/org/traccar/session/state/MotionState.java index e3ce58ab2..6c917ad16 100644 --- a/src/main/java/org/traccar/session/state/MotionState.java +++ b/src/main/java/org/traccar/session/state/MotionState.java @@ -24,6 +24,7 @@ public class MotionState { public static MotionState fromDevice(Device device) { MotionState state = new MotionState(); + state.motionStreak = device.getMotionStreak(); state.motionState = device.getMotionState(); state.motionTime = device.getMotionTime(); state.motionDistance = device.getMotionDistance(); @@ -31,6 +32,7 @@ public class MotionState { } public void toDevice(Device device) { + device.setMotionStreak(motionStreak); device.setMotionState(motionState); device.setMotionTime(motionTime); device.setMotionDistance(motionDistance); @@ -42,6 +44,17 @@ public class MotionState { return changed; } + private boolean motionStreak; + + public boolean getMotionStreak() { + return motionStreak; + } + + public void setMotionStreak(boolean motionStreak) { + this.motionStreak = motionStreak; + changed = true; + } + private boolean motionState; public boolean getMotionState() { diff --git a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java index 25c766b51..b77676dc8 100644 --- a/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java +++ b/src/test/java/org/traccar/handler/events/MotionEventHandlerTest.java @@ -1,6 +1,5 @@ package org.traccar.handler.events; -import org.junit.Ignore; import org.junit.Test; import org.traccar.BaseTest; import org.traccar.model.Event; @@ -62,7 +61,6 @@ public class MotionEventHandlerTest extends BaseTest { verifyState(state, false, 0); } - @Ignore @Test public void testMotionFluctuation() throws ParseException { TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, false, false, 0.01); @@ -87,11 +85,11 @@ public class MotionEventHandlerTest extends BaseTest { MotionProcessor.updateState(state, position("2017-01-01 00:04:00", true, 1000, null), true, tripsConfig); assertNull(state.getEvent()); - verifyState(state, true, 1000); + verifyState(state, true, 0); MotionProcessor.updateState(state, position("2017-01-01 00:06:00", true, 2000, null), true, tripsConfig); assertNull(state.getEvent()); - verifyState(state, true, 2000); + verifyState(state, true, 0); } @Test @@ -99,6 +97,7 @@ public class MotionEventHandlerTest extends BaseTest { TripsConfig tripsConfig = new TripsConfig(500, 300000, 300000, 0, true, false, 0.01); MotionState state = new MotionState(); + state.setMotionStreak(true); state.setMotionState(true); MotionProcessor.updateState(state, position("2017-01-01 00:00:00", false, 100, true), false, tripsConfig); diff --git a/tools/recover.py b/tools/recover.py index dfa94c978..32e3f8721 100755 --- a/tools/recover.py +++ b/tools/recover.py @@ -48,5 +48,5 @@ for session in protocols: s.connect(("localhost", int(port))) for message in messages[session]: s.send(binascii.unhexlify(message)) - time.sleep(0.5) + time.sleep(0.1) s.close() -- cgit v1.2.3 From a4a4907730667425f6f56ace1f79ee8692b9a26c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Dec 2022 17:09:40 -0800 Subject: Add H02 test case --- src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java index 278931466..e68f0814c 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 { var decoder = inject(new H02ProtocolDecoder(null)); + verifyPosition(decoder, buffer( + "*HQ,3177718238,V6,002926,V,3514.4088,N,9733.2842,W,0.00,0.00,151222,FFF7FBFF,310,260,32936,13641,8944501311217563382F,#")); + verifyPosition(decoder, buffer( "*HQ,5905101893,V1,105759,A,37573392,S,145037022,E,000.00,173,280122,FF7FFBFF,,,9059e2c,8232,4#")); -- cgit v1.2.3 From bc2eb6ab65493a18b262ffe49fe79b540862c5db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 15 Dec 2022 07:20:10 -0800 Subject: Decode HHD batch location --- .../traccar/protocol/HuabaoProtocolDecoder.java | 22 +++++++++++++--------- .../protocol/HuabaoProtocolDecoderTest.java | 3 +++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 27a5094a0..cb747fc2e 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -57,6 +57,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_TERMINAL_CONTROL = 0x8105; public static final int MSG_TERMINAL_AUTH = 0x0102; public static final int MSG_LOCATION_REPORT = 0x0200; + public static final int MSG_LOCATION_BATCH_2 = 0x0210; public static final int MSG_ACCELERATION = 0x2070; public static final int MSG_LOCATION_REPORT_2 = 0x5501; public static final int MSG_LOCATION_REPORT_BLIND = 0x5502; @@ -243,11 +244,11 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return decodeLocation2(deviceSession, buf, type); - } else if (type == MSG_LOCATION_BATCH) { + } else if (type == MSG_LOCATION_BATCH || type == MSG_LOCATION_BATCH_2) { sendGeneralResponse(channel, remoteAddress, id, type, index); - return decodeLocationBatch(deviceSession, buf); + return decodeLocationBatch(deviceSession, buf, type); } else if (type == MSG_TIME_SYNC_REQUEST) { @@ -681,21 +682,24 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { return position; } - private List decodeLocationBatch(DeviceSession deviceSession, ByteBuf buf) { + private List decodeLocationBatch(DeviceSession deviceSession, ByteBuf buf, int type) { List positions = new LinkedList<>(); - int count = buf.readUnsignedShort(); - int locationType = buf.readUnsignedByte(); + int locationType = 0; + if (type == MSG_LOCATION_BATCH) { + buf.readUnsignedShort(); // count + locationType = buf.readUnsignedByte(); + } - for (int i = 0; i < count; i++) { - int endIndex = buf.readUnsignedShort() + buf.readerIndex(); - Position position = decodeLocation(deviceSession, buf); + while (buf.readableBytes() > 2) { + int length = type == MSG_LOCATION_BATCH_2 ? buf.readUnsignedByte() : buf.readUnsignedShort(); + ByteBuf fragment = buf.readSlice(length); + Position position = decodeLocation(deviceSession, fragment); if (locationType > 0) { position.set(Position.KEY_ARCHIVE, true); } positions.add(position); - buf.readerIndex(endIndex); } return positions; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 9bbd375dc..2b41f49df 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyPositions(decoder, binary( + "7E021001A2010036526447000A3B00000000000000010158F52206C916B0000000000000161118110121661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110122661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110123661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110124661D019431000B0000CF47006931000B000058A4006930000B0000882400691C00000000000000010158F52206C916B00000000000001611181101253B00000000000000010158F52206C916B0000000000000161118110126661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110127661D019431000B0000CF47006931000B000058A4006930000B0000882400691C00000000000000010158F52206C916B0000000000000161118110128F57E")); + verifyAttribute(decoder, binary( "7e02000042012291302260198f00000000800c012300d2651605ff3188001e0000000022102510310003020000a70400000000ac040000012ce5020003e60b03bc572900ce2eef183200e7030000005c7e"), Position.PREFIX_TEMP + 3, -17.094117647058823); -- cgit v1.2.3 From 1c791638d74998b4451b3c6290c04c46ecd1a9c5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Dec 2022 20:27:29 -0800 Subject: Remove finalizer --- src/main/java/org/traccar/forward/EventForwarderKafka.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main/java/org/traccar/forward/EventForwarderKafka.java b/src/main/java/org/traccar/forward/EventForwarderKafka.java index db97d22de..e65c3a51b 100644 --- a/src/main/java/org/traccar/forward/EventForwarderKafka.java +++ b/src/main/java/org/traccar/forward/EventForwarderKafka.java @@ -43,12 +43,6 @@ public class EventForwarderKafka implements EventForwarder { topic = config.getString(Keys.EVENT_FORWARD_TOPIC); } - @SuppressWarnings("deprecation") - @Override - protected void finalize() { - producer.close(); - } - @Override public void forward(EventData eventData, ResultHandler resultHandler) { try { -- cgit v1.2.3 From ddf72b364323ed3f787fd41c5d5126c3521b96b7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Dec 2022 20:32:01 -0800 Subject: Throw on invalid coordinates --- src/main/java/org/traccar/model/Position.java | 10 ++++++---- .../java/org/traccar/protocol/GlobalstarProtocolDecoder.java | 12 ++++-------- .../java/org/traccar/protocol/BceProtocolDecoderTest.java | 12 +++++++++++- .../org/traccar/protocol/GlobalstarProtocolDecoderTest.java | 2 +- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java index 2b743433a..1286db5f2 100644 --- a/src/main/java/org/traccar/model/Position.java +++ b/src/main/java/org/traccar/model/Position.java @@ -227,9 +227,10 @@ public class Position extends Message { } public void setLatitude(double latitude) { - if (latitude >= -90 && latitude <= 90) { - this.latitude = latitude; + if (latitude < -90 || latitude > 90) { + throw new IllegalArgumentException("Latitude out of range"); } + this.latitude = latitude; } private double longitude; @@ -239,9 +240,10 @@ public class Position extends Message { } public void setLongitude(double longitude) { - if (longitude >= -180 && longitude <= 180) { - this.longitude = longitude; + if (longitude < -180 || longitude > 180) { + throw new IllegalArgumentException("Longitude out of range"); } + this.longitude = longitude; } private double altitude; // value in meters diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java index e537edf1d..0ddb95c14 100644 --- a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java @@ -151,15 +151,11 @@ public class GlobalstarProtocolDecoder extends BaseHttpProtocolDecoder { position.setCourse(BitUtil.from(flags, 5) * 45); - position.setLatitude(buf.readUnsignedMedium() * 90.0 / (1 << 23)); - if (position.getLatitude() > 90) { - position.setLatitude(position.getLatitude() - 180); - } + double latitude = buf.readUnsignedMedium() * 90.0 / (1 << 23); + position.setLatitude(latitude > 90 ? latitude - 180 : latitude); - position.setLongitude(buf.readUnsignedMedium() * 180.0 / (1 << 23)); - if (position.getLongitude() > 180) { - position.setLongitude(position.getLongitude() - 360); - } + double longitude = buf.readUnsignedMedium() * 180.0 / (1 << 23); + position.setLongitude(longitude > 180 ? longitude - 360 : longitude); int speed = buf.readUnsignedByte(); position.setSpeed(UnitsConverter.knotsFromKph(speed)); diff --git a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java index 89ab64cd3..1d980b7e5 100644 --- a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java @@ -1,19 +1,29 @@ package org.traccar.protocol; +import org.junit.Ignore; import org.junit.Test; import org.traccar.ProtocolTest; import org.traccar.model.Position; public class BceProtocolDecoderTest extends ProtocolTest { + @Ignore @Test - public void testDecode() throws Exception { + public void testDecodeFail() throws Exception { var decoder = inject(new BceProtocolDecoder(null)); + // Needs to be fixed verifyPositions(decoder, binary( "18ed450cf3140300c800a53a62972f7bde03c0ffffc0814000e03e354135e34b42121c55fb0000000000d18c060103025d19ab00540000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b5c400000000000000010104080162a72f7bde03c0ffffc0814000ef3e8e4431e34b42061c54fc0000000000d18c060103025d19ab00540000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b5c400000000000000010100000053")); + } + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new BceProtocolDecoder(null)); + verifyNull(decoder, binary( "3ab90b71bc1503000300c10bff11")); diff --git a/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java index f0ba813ca..730d4bb60 100644 --- a/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GlobalstarProtocolDecoderTest.java @@ -29,7 +29,7 @@ public class GlobalstarProtocolDecoderTest extends ProtocolTest { "0-2682225", "1585105370", "N", - "0x8EFE2D97DDEA420018", + "0x00C583EACD37210A00", "", ""))); -- cgit v1.2.3 From 82a6fc308efde0e274b143dd2f5261c30774c3fe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 19 Dec 2022 05:49:00 -0800 Subject: Support JXYD JX08 data --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 7 +++++++ src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index cb747fc2e..60477af8f 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -455,6 +455,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x02: position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.1); break; + case 0x2b: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); + break; case 0x30: position.set(Position.KEY_RSSI, buf.readUnsignedByte()); break; @@ -588,6 +591,9 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; + case 0xF3: + position.set(Position.KEY_ARMED, buf.readUnsignedByte() > 0); + break; case 0xFE: if (length == 1) { position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); @@ -626,6 +632,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } break; default: + System.out.println("subtype " + String.format("%x", subtype)); break; } buf.readerIndex(endIndex); diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 2b41f49df..13b9322c0 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyPosition(decoder, binary( + "7E020000FE069223000241002E00000000000C0003015A98F806C8A1260013000000E622082617464401040000017F02020001030200002504000000002A0200002B0400000000300117310112E306000005890000F3B4000202000000030202F2000402375F00050400000000000602000C000702000C000801320009020072000B020035000C020050000D020176000E0122000F018A00501B4C46504D34414350584731413337303937000000000000000000000052040000000C01000200010101040000000001020200010103040000000101040203E7010C02000E010D020000010E02059B010F020072011002387001110200000112020000011302000001140200000116020000D17E")); + verifyPositions(decoder, binary( "7E021001A2010036526447000A3B00000000000000010158F52206C916B0000000000000161118110121661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110122661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110123661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110124661D019431000B0000CF47006931000B000058A4006930000B0000882400691C00000000000000010158F52206C916B00000000000001611181101253B00000000000000010158F52206C916B0000000000000161118110126661D019431000B0000CF47006931000B000058A4006930000B0000882400693B00000000000000010158F52206C916B0000000000000161118110127661D019431000B0000CF47006931000B000058A4006930000B0000882400691C00000000000000010158F52206C916B0000000000000161118110128F57E")); -- cgit v1.2.3 From 3fa8f496eab4a3a6e9bfac4a8a8ab9b0456720e0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 19 Dec 2022 16:14:05 -0800 Subject: Exclude unused dependencies --- build.gradle | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 297063ce2..a48a07be5 100644 --- a/build.gradle +++ b/build.gradle @@ -84,7 +84,10 @@ dependencies { implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.349" implementation "org.apache.kafka:kafka-clients:3.3.1" - implementation "com.google.firebase:firebase-admin:9.1.1" + implementation("com.google.firebase:firebase-admin:9.1.1") { + exclude group: 'com.google.cloud', module: 'google-cloud-firestore' + exclude group: 'com.google.cloud', module: 'google-cloud-storage' + } testImplementation "junit:junit:4.13.2" testImplementation "org.mockito:mockito-core:4.+" } -- cgit v1.2.3 From 0a8273d87ab5fd4270aab6000d6cefa1472bb024 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 20 Dec 2022 15:47:22 -0800 Subject: Watch general alarm (fix #5006) --- src/main/java/org/traccar/protocol/WatchProtocolDecoder.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java index a71c5606d..142d1b64f 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java @@ -263,6 +263,9 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { Position position = decodePosition(deviceSession, buf.toString(StandardCharsets.US_ASCII)); if (type.startsWith("AL")) { + if (position != null) { + position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + } sendResponse(channel, id, index, "AL"); } -- cgit v1.2.3 From b9cc31bf3ab278df45fa90f6481f929e325326f0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 20 Dec 2022 16:25:24 -0800 Subject: Improve MD500S decoding --- .../org/traccar/protocol/MeitrackProtocolDecoder.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 1935b2c2a..82c8f0087 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -524,12 +524,19 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { paramCount = buf.readUnsignedByte(); for (int j = 0; j < paramCount; j++) { - if (buf.getUnsignedByte(buf.readerIndex()) == 0xFE) { - buf.readUnsignedShort(); // extension id - } else { - buf.readUnsignedByte(); // id + boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; + int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); + int length = buf.readUnsignedByte(); + switch (id) { + case 0xFE31: + buf.readUnsignedByte(); // alarm protocol + buf.readUnsignedByte(); // alarm type + buf.skipBytes(length - 2); + break; + default: + buf.skipBytes(length); + break; } - buf.skipBytes(buf.readUnsignedByte()); // value } positions.add(position); -- cgit v1.2.3 From a7fb4825f1a756b913024c07c78afe626022b8dd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 21 Dec 2022 15:46:10 -0800 Subject: Add test geocoder --- debug.xml | 2 ++ src/main/java/org/traccar/MainModule.java | 4 +++ .../java/org/traccar/geocoder/TestGeocoder.java | 36 ++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/main/java/org/traccar/geocoder/TestGeocoder.java diff --git a/debug.xml b/debug.xml index 7b5c1acff..2569bb8cd 100644 --- a/debug.xml +++ b/debug.xml @@ -10,6 +10,8 @@ true true + test + ./target/media true diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a8f895d3b..078573a60 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -61,6 +61,7 @@ import org.traccar.geocoder.MapmyIndiaGeocoder; import org.traccar.geocoder.NominatimGeocoder; import org.traccar.geocoder.OpenCageGeocoder; import org.traccar.geocoder.PositionStackGeocoder; +import org.traccar.geocoder.TestGeocoder; import org.traccar.geocoder.TomTomGeocoder; import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; @@ -181,6 +182,9 @@ public class MainModule extends AbstractModule { int cacheSize = config.getInteger(Keys.GEOCODER_CACHE_SIZE); Geocoder geocoder; switch (type) { + case "test": + geocoder = new TestGeocoder(); + break; case "nominatim": geocoder = new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); break; diff --git a/src/main/java/org/traccar/geocoder/TestGeocoder.java b/src/main/java/org/traccar/geocoder/TestGeocoder.java new file mode 100644 index 000000000..259f13c6c --- /dev/null +++ b/src/main/java/org/traccar/geocoder/TestGeocoder.java @@ -0,0 +1,36 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.geocoder; + +import org.traccar.database.StatisticsManager; + +public class TestGeocoder implements Geocoder { + + @Override + public void setStatisticsManager(StatisticsManager statisticsManager) { + } + + @Override + public String getAddress(double latitude, double longitude, ReverseGeocoderCallback callback) { + String address = String.format("Location %f, %f", latitude, longitude); + if (callback != null) { + callback.onSuccess(address); + return null; + } + return address; + } + +} -- cgit v1.2.3 From 13156bb9d7c92dac8bd775e936946b3de08f0732 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 22 Dec 2022 11:36:24 -0800 Subject: Remove subtype logging --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index 60477af8f..cb32e4a38 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -632,7 +632,6 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { } break; default: - System.out.println("subtype " + String.format("%x", subtype)); break; } buf.readerIndex(endIndex); -- cgit v1.2.3 From 81aac9fbdd85db06b4f5162b39edd3c039cc7dec Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 22 Dec 2022 13:11:51 -0800 Subject: Add JXYD JX06 parameters --- .../traccar/protocol/HuabaoProtocolDecoder.java | 61 +++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index cb32e4a38..f08c2afa4 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -592,7 +592,66 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; case 0xF3: - position.set(Position.KEY_ARMED, buf.readUnsignedByte() > 0); + while (buf.readerIndex() < endIndex) { + int extendedType = buf.readUnsignedShort(); + int extendedLength = buf.readUnsignedByte(); + switch (extendedType) { + case 0x0002: + position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); + break; + case 0x0003: + position.set(Position.KEY_RPM, buf.readUnsignedShort()); + break; + case 0x0004: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + break; + case 0x0005: + position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 100); + break; + case 0x0007: + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.1); + break; + case 0x0008: + position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedShort() * 0.1); + break; + case 0x0009: + position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedShort() - 40); + break; + case 0x000B: + position.set("intakePressure", buf.readUnsignedShort()); + break; + case 0x000C: + position.set("intakeTemp", buf.readUnsignedShort() - 40); + break; + case 0x000D: + position.set("intakeFlow", buf.readUnsignedShort()); + break; + case 0x000E: + position.set(Position.KEY_THROTTLE, buf.readUnsignedShort() * 100 / 255); + break; + case 0x0050: + position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII)); + break; + case 0x0100: + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 0.1); + break; + case 0x0102: + position.set("tripFuel", buf.readUnsignedShort() * 0.1); + break; + case 0x0112: + position.set("hardAccelerationCount", buf.readUnsignedShort()); + break; + case 0x0113: + position.set("hardDecelerationCount", buf.readUnsignedShort()); + break; + case 0x0114: + position.set("hardCorneringCount", buf.readUnsignedShort()); + break; + default: + buf.skipBytes(extendedLength); + break; + } + } break; case 0xFE: if (length == 1) { -- cgit v1.2.3 From fdc1997909043b128b358e4404260b3fbff8c289 Mon Sep 17 00:00:00 2001 From: Svetoslav Batchovski Date: Wed, 21 Dec 2022 22:51:51 +0100 Subject: MQTT EventForwarder added --- build.gradle | 1 + src/main/java/org/traccar/MainModule.java | 13 ++- .../org/traccar/forward/EventForwarderMqtt.java | 103 +++++++++++++++++++++ 3 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/traccar/forward/EventForwarderMqtt.java diff --git a/build.gradle b/build.gradle index a48a07be5..91ba2cd5c 100644 --- a/build.gradle +++ b/build.gradle @@ -84,6 +84,7 @@ dependencies { implementation "javax.activation:activation:1.1.1" implementation "com.amazonaws:aws-java-sdk-sns:1.12.349" implementation "org.apache.kafka:kafka-clients:3.3.1" + implementation 'com.hivemq:hivemq-mqtt-client:1.3.0' implementation("com.google.firebase:firebase-admin:9.1.1") { exclude group: 'com.google.cloud', module: 'google-cloud-firestore' exclude group: 'com.google.cloud', module: 'google-cloud-storage' diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index a8f895d3b..55b26010f 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -38,6 +38,7 @@ import org.traccar.database.StatisticsManager; import org.traccar.forward.EventForwarder; import org.traccar.forward.EventForwarderJson; import org.traccar.forward.EventForwarderKafka; +import org.traccar.forward.EventForwarderMqtt; import org.traccar.forward.PositionForwarder; import org.traccar.forward.PositionForwarderJson; import org.traccar.forward.PositionForwarderKafka; @@ -322,10 +323,14 @@ public class MainModule extends AbstractModule { @Provides public static EventForwarder provideEventForwarder(Config config, Client client, ObjectMapper objectMapper) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { - if (config.getString(Keys.EVENT_FORWARD_TYPE).equals("kafka")) { - return new EventForwarderKafka(config, objectMapper); - } else { - return new EventForwarderJson(config, client); + String forwardType = config.getString(Keys.EVENT_FORWARD_TYPE); + switch (forwardType) { + case "kafka": + return new EventForwarderKafka(config, objectMapper); + case "mqtt": + return new EventForwarderMqtt(config, objectMapper); + default: + return new EventForwarderJson(config, client); } } return null; diff --git a/src/main/java/org/traccar/forward/EventForwarderMqtt.java b/src/main/java/org/traccar/forward/EventForwarderMqtt.java new file mode 100644 index 000000000..dc95cb4e2 --- /dev/null +++ b/src/main/java/org/traccar/forward/EventForwarderMqtt.java @@ -0,0 +1,103 @@ +/* + * Copyright 2022 Anton Tananaev (anton@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.forward; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.UUID; + +public class EventForwarderMqtt implements EventForwarder { + + private static final Logger LOGGER = LoggerFactory.getLogger(EventForwarderMqtt.class); + private final Mqtt5AsyncClient client; + private final ObjectMapper objectMapper; + + private final String topic; + + public EventForwarderMqtt(Config config, ObjectMapper objectMapper) { + URI url; + try { + url = new URI(config.getString(Keys.EVENT_FORWARD_URL)); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + + String userInfo = url.getUserInfo(); + Mqtt5SimpleAuth simpleAuth = null; + if (userInfo != null) { + int delimiter = userInfo.indexOf(':'); + if (delimiter == -1) { + throw new IllegalArgumentException("Wrong credentials. Should be in format \"username:password\""); + } else { + simpleAuth = Mqtt5SimpleAuth.builder() + .username(userInfo.substring(0, delimiter++)) + .password(userInfo.substring(delimiter).getBytes()) + .build(); + } + } + + String host = url.getHost(); + int port = url.getPort(); + client = Mqtt5Client.builder() + .identifier("traccar-" + UUID.randomUUID().toString()) + .serverHost(host) + .serverPort(port) + .simpleAuth(simpleAuth) + .automaticReconnectWithDefaultConfig() + .buildAsync(); + + client.connectWith() + .send() + .whenComplete((message, e) -> { + if (e != null) { + throw new RuntimeException(e); + } + }); + + this.objectMapper = objectMapper; + topic = config.getString(Keys.EVENT_FORWARD_TOPIC); + } + + @Override + public void forward(EventData eventData, ResultHandler resultHandler) { + byte[] payload; + try { + payload = objectMapper.writeValueAsString(eventData).getBytes(); + } catch (JsonProcessingException e) { + resultHandler.onResult(false, e); + return; + } + + client.publishWith() + .topic(topic) + .qos(MqttQos.AT_LEAST_ONCE) + .payload(payload) + .send() + .whenComplete((message, e) -> resultHandler.onResult(e == null, e)); + } + +} -- cgit v1.2.3 From 2e1b77d6aa5a2c2d2e07b29f80c40ec741004819 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 24 Dec 2022 11:41:14 -0800 Subject: Extend Iridium format --- src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java | 4 ++-- src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java index 0306770b6..0e1c7568b 100644 --- a/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tr20ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +52,7 @@ public class Tr20ProtocolDecoder extends BaseProtocolDecoder { .number("(ddd)(dd.d+),") // longitude .number("(d+),") // speed .number("(d+),") // course - .number("(?:NA|[FC]?(-?d+)[^,]*),") // temperature + .number("(?:NA|[BFC]?(-?d+)[^,]*),") // temperature .number("(x{8}),") // status .number("(d+)") // event .any() diff --git a/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java index c4513cbdc..e4917c872 100644 --- a/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tr20ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Tr20ProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Tr20ProtocolDecoder(null)); + verifyPosition(decoder, text( + "%%m13,L,221221103115,N1237.2271W00801.9500,000,000,B13.1:F0.0,04020000,253,CFG:133.00|")); + verifyPosition(decoder, text( "%%TR20GRANT,L,210602170135,N0951.1733W08356.7672,000,000,C80:F0,00020008,108,CFG:6980.00|")); -- cgit v1.2.3 From 6c8fdbbf5f44db7eb88bc75dbaf89c679aa25cd5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 28 Dec 2022 07:52:24 -0800 Subject: Fix event and ignition --- .../java/org/traccar/protocol/CellocatorProtocolDecoder.java | 10 ++++++---- .../org/traccar/protocol/CellocatorProtocolDecoderTest.java | 5 +++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java index 07f7f1692..3573a95ca 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -119,14 +119,16 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_STATUS, buf.readUnsignedByte() & 0x0f); buf.readUnsignedByte(); // operator / configuration flags - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + buf.readUnsignedByte(); // reason data + short event = buf.readUnsignedByte(); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); position.set("mode", buf.readUnsignedByte()); - long input = buf.readUnsignedIntLE(); + long input = buf.readUnsignedInt(); + position.set(Position.KEY_IGNITION, BitUtil.check(input, 3 * 8 + 5)); position.set(Position.KEY_DOOR, BitUtil.check(input, 3 * 8)); - position.set(Position.KEY_IGNITION, BitUtil.check(input, 2 * 8 + 7)); position.set(Position.KEY_CHARGE, BitUtil.check(input, 7)); position.set(Position.KEY_INPUT, input); diff --git a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java index 7e96b073b..27cad39a3 100644 --- a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java @@ -2,6 +2,7 @@ package org.traccar.protocol; import org.junit.Test; import org.traccar.ProtocolTest; +import org.traccar.model.Position; public class CellocatorProtocolDecoderTest extends ProtocolTest { @@ -10,6 +11,10 @@ public class CellocatorProtocolDecoderTest extends ProtocolTest { var decoder = inject(new CellocatorProtocolDecoder(null)); + verifyAttribute(decoder, binary( + "4d4347500098ab31000856b12b2c041016002c0023b3000021f3f5ffb04c8f0100000000000078dd0004020f716445f75f3b0701126e0200b303000036002538151b0ce607ab"), + Position.KEY_IGNITION, true); + verifyPosition(decoder, binary( "4D43475000856308000004B2DE1F04009E00200100000000696CF7AB002F1A00000000000000325C000402069BFDE70857E22502F41C000036000000DF0B0932100B09DC0719")); -- cgit v1.2.3 From 32d276ee8d3595a9f3290b96ca0b6bdd6140b7b4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 30 Dec 2022 17:03:04 -0800 Subject: Improve JM-LL301 support --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 31 ++++++++++++++++++---- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 4 +++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 212b4245f..15588c89b 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -100,7 +100,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_WIFI_3 = 0xA2; // GK310 public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 public static final int MSG_FENCE_MULTI = 0xA4; // GK310 - public static final int MSG_LBS_ALARM = 0xA5; // GK310 + public static final int MSG_LBS_ALARM = 0xA5; // GK310 & JM-LL301 public static final int MSG_LBS_ADDRESS = 0xA7; // GK310 public static final int MSG_OBD = 0x8C; // FM08ABC public static final int MSG_DTC = 0x65; // FM08ABC @@ -209,6 +209,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: case MSG_GPS_LBS_STATUS_4: + case MSG_LBS_ALARM: return true; default: return false; @@ -334,9 +335,26 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } int mcc = buf.readUnsignedShort(); - int mnc = BitUtil.check(mcc, 15) || type == MSG_GPS_LBS_6 ? buf.readUnsignedShort() : buf.readUnsignedByte(); - int lac = buf.readUnsignedShort(); - long cid = type == MSG_GPS_LBS_6 ? buf.readUnsignedInt() : buf.readUnsignedMedium(); + int mnc; + if (BitUtil.check(mcc, 15) || type == MSG_GPS_LBS_6) { + mnc = buf.readUnsignedShort(); + } else { + mnc = buf.readUnsignedByte(); + } + int lac; + if (type == MSG_LBS_ALARM) { + lac = buf.readInt(); + } else { + lac = buf.readUnsignedShort(); + } + long cid; + if (type == MSG_LBS_ALARM) { + cid = buf.readLong(); + } else if (type == MSG_GPS_LBS_6) { + cid = buf.readUnsignedInt(); + } else { + cid = buf.readUnsignedMedium(); + } position.setNetwork(new Network(CellTower.from(BitUtil.to(mcc, 15), mnc, lac, cid))); @@ -401,6 +419,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_OVERSPEED; case 0x0E: case 0x0F: + case 0x19: return Position.ALARM_LOW_BATTERY; case 0x11: return Position.ALARM_POWER_OFF; @@ -410,6 +429,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_TAMPERING; case 0x14: return Position.ALARM_DOOR; + case 0x18: + return Position.ALARM_REMOVING; case 0x23: return Position.ALARM_FALL_DOWN; case 0x29: @@ -783,7 +804,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasLbs(type)) { - decodeLbs(position, buf, type, hasStatus(type)); + decodeLbs(position, buf, type, hasStatus(type) && type != MSG_LBS_ALARM); } if (hasStatus(type)) { diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index d1789bb16..9d0716c7d 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,10 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyAttribute(decoder, binary( + "787819a5012ed0000075df000000000098661502050413000019a12b0d0a"), + Position.KEY_ALARM, Position.ALARM_TAMPERING); + verifyAttribute(decoder, binary( "7878131302801900002e42016f000000003a0177ef180d0a"), Position.KEY_POWER, 3.67); -- cgit v1.2.3 From 67964087deaa12557ac3c48b537ee22475f82f5d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 31 Dec 2022 16:46:38 -0800 Subject: Decode G1A cell info --- src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java | 7 +++++++ src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index f08c2afa4..d0bbeebb5 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -571,6 +571,13 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x00CE: position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); break; + case 0x00D8: + Network network = new Network(); + network.addCellTower(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedByte(), + buf.readUnsignedShort(), buf.readUnsignedInt())); + position.setNetwork(network); + break; case 0xE1: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); break; diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 13b9322c0..e91c84d79 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e010200204f07788ef67601824f4459344f544d314d4459774d4441314d444977626d5633553235536457786cba7e")); + verifyPosition(decoder, binary( + "7e0200004107904226220608ca0000010000000010031dac0d004864f30000000000002212291003220104000179a7300107310100eb17000300e151000300e304000b00d801041edf340000306b007e")); + verifyPosition(decoder, binary( "7E020000FE069223000241002E00000000000C0003015A98F806C8A1260013000000E622082617464401040000017F02020001030200002504000000002A0200002B0400000000300117310112E306000005890000F3B4000202000000030202F2000402375F00050400000000000602000C000702000C000801320009020072000B020035000C020050000D020176000E0122000F018A00501B4C46504D34414350584731413337303937000000000000000000000052040000000C01000200010101040000000001020200010103040000000101040203E7010C02000E010D020000010E02059B010F020072011002387001110200000112020000011302000001140200000116020000D17E")); -- cgit v1.2.3 From 42f269d5f9e0829c7dbfa22ccb6b41415e6e4415 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 1 Jan 2023 11:10:35 -0800 Subject: Rename config script --- tools/config-doc.py | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/gen_config_doc.py | 102 ------------------------------------------------ 2 files changed, 102 insertions(+), 102 deletions(-) create mode 100755 tools/config-doc.py delete mode 100644 tools/gen_config_doc.py diff --git a/tools/config-doc.py b/tools/config-doc.py new file mode 100755 index 000000000..98266386e --- /dev/null +++ b/tools/config-doc.py @@ -0,0 +1,102 @@ +#!/usr/bin/python + +import re +import os +import argparse + +_KEYS_FILE = os.path.join( + os.path.dirname(__file__), "../src/main/java/org/traccar/config/Keys.java" +) + + +def get_config_keys(): + """Parses Keys.java to extract keys to be used in configuration files + + Args: None + + Returns: + list: A list of dict containing the following keys - + 'key': A dot separated name of the config key + 'description': A list of str + """ + desc_re = re.compile(r"(/\*\*\n|\s+\*/|\s+\*)") + key_match_re = re.compile(r"\(\n(.+)\);", re.DOTALL) + key_split_re = re.compile(r",\s+", re.DOTALL) + keys = [] + + with open(_KEYS_FILE, "r") as f: + config = re.findall( + r"(/\*\*.*?\*/)\n\s+(public static final Config.*?;)", f.read(), re.DOTALL + ) + for i in config: + try: + key_match = key_match_re.search(i[1]) + if key_match: + terms = [x.strip() for x in key_split_re.split(key_match.group(1))] + key = terms[0].replace('"', "") + description = [ + x.strip().replace("\n", "") + for x in desc_re.sub("\n", i[0]).strip().split("\n\n") + ] + if len(terms) == 3: + description.append(f"Default: {terms[2]}") + keys.append( + { + "key": key, + "description": description, + } + ) + except IndexError: + # will continue if key_match.group(1) or terms[0] does not exist + # for some reason + pass + + return keys + + +def get_html(): + return ("\n").join( + [ + f"""
+
+
+ {x["key"]} config +
+

+ {"
".join(x["description"])} +

+
+
""" + for x in get_config_keys() + ] + ) + + +def get_pug(): + return ("\n").join( + [ + f""" div(class='card mt-3') + div(class='card-body') + h5(class='card-title') {x["key"]} #[span(class='badge badge-dark') config] + p(class='card-text') {"#[br] ".join(x["description"])}""" + for x in get_config_keys() + ] + ) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Parses Keys.java to extract keys to be used in configuration files" + ) + parser.add_argument( + "--format", choices=["pug", "html"], default="pug", help="default: 'pug'" + ) + args = parser.parse_args() + + def get_output(): + if args.format == 'html': + return get_html() + + return get_pug() + + print(get_output()) \ No newline at end of file diff --git a/tools/gen_config_doc.py b/tools/gen_config_doc.py deleted file mode 100644 index 98266386e..000000000 --- a/tools/gen_config_doc.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python - -import re -import os -import argparse - -_KEYS_FILE = os.path.join( - os.path.dirname(__file__), "../src/main/java/org/traccar/config/Keys.java" -) - - -def get_config_keys(): - """Parses Keys.java to extract keys to be used in configuration files - - Args: None - - Returns: - list: A list of dict containing the following keys - - 'key': A dot separated name of the config key - 'description': A list of str - """ - desc_re = re.compile(r"(/\*\*\n|\s+\*/|\s+\*)") - key_match_re = re.compile(r"\(\n(.+)\);", re.DOTALL) - key_split_re = re.compile(r",\s+", re.DOTALL) - keys = [] - - with open(_KEYS_FILE, "r") as f: - config = re.findall( - r"(/\*\*.*?\*/)\n\s+(public static final Config.*?;)", f.read(), re.DOTALL - ) - for i in config: - try: - key_match = key_match_re.search(i[1]) - if key_match: - terms = [x.strip() for x in key_split_re.split(key_match.group(1))] - key = terms[0].replace('"', "") - description = [ - x.strip().replace("\n", "") - for x in desc_re.sub("\n", i[0]).strip().split("\n\n") - ] - if len(terms) == 3: - description.append(f"Default: {terms[2]}") - keys.append( - { - "key": key, - "description": description, - } - ) - except IndexError: - # will continue if key_match.group(1) or terms[0] does not exist - # for some reason - pass - - return keys - - -def get_html(): - return ("\n").join( - [ - f"""
-
-
- {x["key"]} config -
-

- {"
".join(x["description"])} -

-
-
""" - for x in get_config_keys() - ] - ) - - -def get_pug(): - return ("\n").join( - [ - f""" div(class='card mt-3') - div(class='card-body') - h5(class='card-title') {x["key"]} #[span(class='badge badge-dark') config] - p(class='card-text') {"#[br] ".join(x["description"])}""" - for x in get_config_keys() - ] - ) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description="Parses Keys.java to extract keys to be used in configuration files" - ) - parser.add_argument( - "--format", choices=["pug", "html"], default="pug", help="default: 'pug'" - ) - args = parser.parse_args() - - def get_output(): - if args.format == 'html': - return get_html() - - return get_pug() - - print(get_output()) \ No newline at end of file -- cgit v1.2.3 From aa6db4e57ceb30377678c5c563c4992161de0ffe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 1 Jan 2023 11:42:08 -0800 Subject: Update config script --- tools/config-doc.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/config-doc.py b/tools/config-doc.py index 98266386e..c55b2b5ef 100755 --- a/tools/config-doc.py +++ b/tools/config-doc.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 import re import os @@ -22,6 +22,7 @@ def get_config_keys(): desc_re = re.compile(r"(/\*\*\n|\s+\*/|\s+\*)") key_match_re = re.compile(r"\(\n(.+)\);", re.DOTALL) key_split_re = re.compile(r",\s+", re.DOTALL) + types_match_re = re.compile(r"List\.of\(([^)]+)\)", re.DOTALL) keys = [] with open(_KEYS_FILE, "r") as f: @@ -34,16 +35,18 @@ def get_config_keys(): if key_match: terms = [x.strip() for x in key_split_re.split(key_match.group(1))] key = terms[0].replace('"', "") + key = "[protocol]" + key if key.startswith('.') else key description = [ x.strip().replace("\n", "") for x in desc_re.sub("\n", i[0]).strip().split("\n\n") ] - if len(terms) == 3: - description.append(f"Default: {terms[2]}") + types_match = types_match_re.search(i[1]) + types = map(lambda x: x[8:].lower(), types_match[1].split(", ")) keys.append( { "key": key, "description": description, + "types": types, } ) except IndexError: @@ -60,7 +63,7 @@ def get_html(): f"""
- {x["key"]} config + {x["key"]}

{"
".join(x["description"])} @@ -77,7 +80,7 @@ def get_pug(): [ f""" div(class='card mt-3') div(class='card-body') - h5(class='card-title') {x["key"]} #[span(class='badge badge-dark') config] + h5(class='card-title') {x["key"]} {" ".join(map("#[span(class='badge badge-dark') {:}]".format, x["types"]))} p(class='card-text') {"#[br] ".join(x["description"])}""" for x in get_config_keys() ] @@ -99,4 +102,4 @@ if __name__ == "__main__": return get_pug() - print(get_output()) \ No newline at end of file + print(get_output()) -- cgit v1.2.3 From 2ed386ecd1fa6b51cf3115fe6fe4626ebfceea31 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 2 Jan 2023 15:01:37 -0800 Subject: Handle T55 new line --- src/main/java/org/traccar/protocol/T55ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 51f06a801..3be161fb8 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -365,7 +365,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - String sentence = (String) msg; + String sentence = ((String) msg).trim(); DeviceSession deviceSession; -- cgit v1.2.3 From 046076aeb6f0c79bb59ef9aead4ebbc23e286c63 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 3 Jan 2023 09:36:23 -0800 Subject: Handle ZX303 variation --- src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 15588c89b..ef09677bf 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -803,7 +803,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); } - if (hasLbs(type)) { + if (hasLbs(type) && buf.readableBytes() > 6) { decodeLbs(position, buf, type, hasStatus(type) && type != MSG_LBS_ALARM); } diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 9d0716c7d..23c29b0d3 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -17,6 +17,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyPosition(decoder, binary( + "78781511170103100e1f9904efe30400a97f88003410ffdd000d0a")); + verifyAttribute(decoder, binary( "787819a5012ed0000075df000000000098661502050413000019a12b0d0a"), Position.KEY_ALARM, Position.ALARM_TAMPERING); -- cgit v1.2.3 From cf5379247a8de3a21016c8a74a6b9c9ac1b81fab Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 5 Jan 2023 09:37:54 -0800 Subject: Fix activity decoding --- src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index eb5e16de2..0b08badb8 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -272,8 +272,8 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { case 0x31: int i = 1; while (buf.readerIndex() < endIndex) { - position.set("activity" + i + "Time", buf.readUnsignedInt()); - position.set("activity" + i, buf.readUnsignedInt()); + position.set("activity" + i + "Time", buf.readUnsignedIntLE()); + position.set("activity" + i, buf.readUnsignedIntLE()); i += 1; } break; -- cgit v1.2.3 From b76e00c283c79f29ad13fff70b882ae6d3685aa5 Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:19:05 +0000 Subject: lbs-for-tlt2h-added --- .../org/traccar/protocol/Tlt2hProtocolDecoder.java | 50 +++++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java index 3d219fc09..be8de448d 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -17,6 +17,7 @@ package org.traccar.protocol; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.model.CellTower; import org.traccar.session.DeviceSession; import org.traccar.Protocol; import org.traccar.helper.DateBuilder; @@ -55,6 +56,12 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_POSITION = new PatternBuilder() .text("#") .number("(?:(dd)|x*)") // cell or voltage + .groupBegin() + .number("#(d+),") // mcc + .number("(d+),") // mnc + .number("(x+),") // lac + .number("(x+)") // cell id + .groupEnd("?") .text("$GPRMC,") .number("(dd)(dd)(dd).d+,") // time (hhmmss.sss) .expression("([AVL]),") // validity @@ -71,6 +78,12 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_WIFI = new PatternBuilder() .text("#") .number("(?:(dd)|x+)") // cell or voltage + .groupBegin() + .number("#(d+),") // mcc + .number("(d+),") // mnc + .number("(x+),") // lac + .number("(x+)") // cell id + .groupEnd("?") .text("$WIFI,") .number("(dd)(dd)(dd).d+,") // time (hhmmss.sss) .expression("[AVL],") // validity @@ -168,17 +181,35 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextInt() * 0.1); } + if (parser.hasNext(4)) { + Network network = new Network(); + network.addCellTower(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt())); + position.setNetwork(network); + } + 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(0)); - position.setCourse(parser.nextDouble(0)); + boolean isPositionValid = parser.next().equals("A"); + position.setValid(isPositionValid); + + if(isPositionValid) { + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setSpeed(parser.nextDouble(0)); + position.setCourse(parser.nextDouble(0)); + } else { + parser.skip(8); + } dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); + + if(isPositionValid) { + position.setTime(dateBuilder.getDate()); + } else { + getLastLocation(position, dateBuilder.getDate()); + } } else { continue; @@ -191,11 +222,16 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, parser.nextInt() * 0.1); + Network network = new Network(); + if (parser.hasNext(4)) { + network.addCellTower(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt())); + } + DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); String[] values = parser.next().split(","); - Network network = new Network(); for (int i = 0; i < values.length / 2; i++) { String mac = values[i * 2 + 1].replaceAll("(..)", "$1:").substring(0, 17); network.addWifiAccessPoint(WifiAccessPoint.from(mac, Integer.parseInt(values[i * 2]))); -- cgit v1.2.3 From 7978a2a1349c3d89d79553c3fe703e4ea0559d32 Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:20:04 +0000 Subject: test-case-for-tlt2h-lbs-added --- src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java index 40d9ff34d..a6a9f836e 100644 --- a/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Tlt2hProtocolDecoderTest.java @@ -81,6 +81,13 @@ public class Tlt2hProtocolDecoderTest extends ProtocolTest { "#357671031289215#V600#0000#AUTOLOW#1\r\n", "#00735e1c$GPRMC,115647.000,A,5553.6524,N,02632.3128,E,0.00,0.0,130614,0.0,W,A*28")); + verifyPositions(decoder, false, text( + "#860186058100000#MT700#0000#AUTO#1\r\n", + "#39#262,03,8CE6,A672$WIFI,154928.00,A,-74,3CA62F52615B,-82,A0E4CB83852D,,,050123*28\r\n##\r\n")); + + verifyPositions(decoder, false, text( + "#860186058100000#MT700#0000#AUTO#1\r\n", + "#39#262,03,8CE6,A672$GPRMC,115419.00,V,,,,,,,050123,,,A*7D\r\n##\r\n")); } } -- cgit v1.2.3 From c1cbda022e33d56e9f77a9e26da59e88061c469f Mon Sep 17 00:00:00 2001 From: wkhaksar <31837615+wkhaksar@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:39:34 +0000 Subject: style-fixed --- src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java index be8de448d..7976b825f 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -194,7 +194,7 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { boolean isPositionValid = parser.next().equals("A"); position.setValid(isPositionValid); - if(isPositionValid) { + if (isPositionValid) { position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); position.setSpeed(parser.nextDouble(0)); @@ -204,8 +204,8 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { } dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - - if(isPositionValid) { + + if (isPositionValid) { position.setTime(dateBuilder.getDate()); } else { getLastLocation(position, dateBuilder.getDate()); -- cgit v1.2.3 From c6e7f17791f5721c994128c8165c71bcb40a02fb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 6 Jan 2023 19:44:12 -0800 Subject: Fix TLT2H LBS decoding --- .../org/traccar/protocol/Tlt2hProtocolDecoder.java | 25 ++++++---------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java index 7976b825f..e85bdf9b3 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -191,25 +191,14 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { DateBuilder dateBuilder = new DateBuilder() .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - boolean isPositionValid = parser.next().equals("A"); - position.setValid(isPositionValid); - - if (isPositionValid) { - position.setLatitude(parser.nextCoordinate()); - position.setLongitude(parser.nextCoordinate()); - position.setSpeed(parser.nextDouble(0)); - position.setCourse(parser.nextDouble(0)); - } else { - parser.skip(8); - } + position.setValid(parser.next().equals("A")); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setSpeed(parser.nextDouble(0)); + position.setCourse(parser.nextDouble(0)); dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - - if (isPositionValid) { - position.setTime(dateBuilder.getDate()); - } else { - getLastLocation(position, dateBuilder.getDate()); - } + position.setTime(dateBuilder.getDate()); } else { continue; -- cgit v1.2.3 From 27a9aabcff99582bab762890ea0c6d4395a532aa Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 9 Jan 2023 08:20:45 -0800 Subject: Add ST4315 test case --- .../protocol/SuntechProtocolDecoderTest.java | 143 +++++++++++---------- 1 file changed, 73 insertions(+), 70 deletions(-) diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java index e25ad124c..107c03d36 100644 --- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -8,80 +8,12 @@ import org.traccar.model.Position; public class SuntechProtocolDecoderTest extends ProtocolTest { @Test - public void testDecodeTemperature() throws Exception { + public void testDecode() throws Exception { var decoder = inject(new SuntechProtocolDecoder(null)); - decoder.setHbm(true); - decoder.setIncludeAdc(true); - - verifyAttribute(decoder, buffer( - "ST600STT;008594432;20;492;20200212;18:58:30;060bb0e1;334;20;36bb;45;+19.337897;-099.064489;000.398;000.00;12;1;5049883;13.61;100100;2;1198;013762;4.2;1;4.68"), - Position.PREFIX_ADC + 1, 4.68); - - decoder.setIncludeTemp(true); - - verifyAttribute(decoder, buffer( - "ST600STT;008350848;35;523;20191102;13:49:46;0bf14fdb;334;20;2f19;57;+20.466737;-100.825455;000.006;000.00;11;1;10274175;11.36;00000000;1;0300;018353;4.2;1;0.00;;;;00000000000000;0;28EE56B911160234:+13.7;:;:"), - Position.PREFIX_TEMP + 2, 13.7); - verifyPosition(decoder, buffer( - "ST300STT;205173382;07;564;20160322;23:23:18;232e19;+19.288278;-099.128750;000.122;000.00;9;1;478391;11.53;000100;1;9498;079324;4.3;1;0.00;0.00;0.00;00000000000000;0;2898E16006000058:-20.8;2861626006000039:+2.5;:")); - - verifyPosition(decoder, buffer( - "ST300EVT;205173382;07;564;20160322;23:23:18;232e19;+19.288278;-099.128750;000.122;000.00;9;1;478391;11.53;000100;2;1;9498;079324;4.3;1;0.00;0.00;0.00;00000000000000;0;2898E16006000058:-20.8;2861626006000039:+2.5;:")); - - verifyPosition(decoder, buffer( - "ST600STT;008349958;35;523;20181112;00:49:30;0bf10d4e;334;20;2f19;22;+20.552718;-100.824478;050.021;095.41;12;1;1303603;14.30;10000000;4;8911;001987;4.1;0;0.00;;;;00000000000000;0;2826C8A70800000C:+26.6;:;:")); - - } - - @Test - public void testDecodeRpm() throws Exception { - - var decoder = inject(new SuntechProtocolDecoder(null)); - - decoder.setHbm(true); - decoder.setIncludeRpm(true); - - verifyAttribute(decoder, buffer( - "ST300STT;907131077;04;706;20190227;23:59:34;cc719;-12.963490;-038.499587;000.067;000.00;7;1;57095;12.50;000000;1;0337;000207;0.0;1;0;012E717F010000;1"), - Position.KEY_RPM, 0); - - } - - @Test - public void testDecodeHours() throws Exception { - - var decoder = inject(new SuntechProtocolDecoder(null)); - - decoder.setHbm(true); - - verifyAttribute(decoder, buffer( - "ST300ALT;007239104;40;313;20190112;01:07:16;c99139;+04.703287;-074.148897;000.000;189.72;21;1;425512;12.61;100000;33;003188;4.1;1"), - Position.KEY_HOURS, 3188 * 60000L); - - } - - @Test - public void testDecodeDriver() throws Exception { - - var decoder = inject(new SuntechProtocolDecoder(null)); - - verifyAttribute(decoder, buffer( - "ST300HTE;511050566;45;308;20200909;13:38:38;0;12.50;001354;0.0;1;0;1;1;0;-27.636632;-052.277933;-27.636675;-052.277947;000.000;002.296;0;00000000000000"), - Position.KEY_DRIVER_UNIQUE_ID, "00000000000000"); - - verifyAttribute(decoder, buffer( - "ST300HTE;100850001;04;248;20110101;00:13:52;167559;12.28;004005;0.0;1;0;3;3;0;-22.881018;-047.070831;-22.881018;-047.070831;000.000;000.000;0;0;3;0;0;0;01E04D44160000"), - Position.KEY_DRIVER_UNIQUE_ID, "01E04D44160000"); - - } - - @Test - public void testDecode() throws Exception { - - var decoder = inject(new SuntechProtocolDecoder(null)); + "ALT;0840037569;FFFFFF;84;1.0.6;0;20221228;11:33:05;00004490;724;11;05D3;33;-22.845935;-46.322000;0.00;0.00;18;0;00000001;00000000;99;;;;08E3800F;4.1;12.37;0;0;0;0;4;;;;")); verifyAttribute(decoder, buffer( "ALT;0950030205;3FFFFF;95;1.0.11;0;20221017;21:41:30;02F2F402;334;20;0F1D;45;+25.791061;-100.170745;0.00;0.00;18;1;00000101;00000000;42;2;"), @@ -289,4 +221,75 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { } + @Test + public void testDecodeTemperature() throws Exception { + + var decoder = inject(new SuntechProtocolDecoder(null)); + + decoder.setHbm(true); + decoder.setIncludeAdc(true); + + verifyAttribute(decoder, buffer( + "ST600STT;008594432;20;492;20200212;18:58:30;060bb0e1;334;20;36bb;45;+19.337897;-099.064489;000.398;000.00;12;1;5049883;13.61;100100;2;1198;013762;4.2;1;4.68"), + Position.PREFIX_ADC + 1, 4.68); + + decoder.setIncludeTemp(true); + + verifyAttribute(decoder, buffer( + "ST600STT;008350848;35;523;20191102;13:49:46;0bf14fdb;334;20;2f19;57;+20.466737;-100.825455;000.006;000.00;11;1;10274175;11.36;00000000;1;0300;018353;4.2;1;0.00;;;;00000000000000;0;28EE56B911160234:+13.7;:;:"), + Position.PREFIX_TEMP + 2, 13.7); + + verifyPosition(decoder, buffer( + "ST300STT;205173382;07;564;20160322;23:23:18;232e19;+19.288278;-099.128750;000.122;000.00;9;1;478391;11.53;000100;1;9498;079324;4.3;1;0.00;0.00;0.00;00000000000000;0;2898E16006000058:-20.8;2861626006000039:+2.5;:")); + + verifyPosition(decoder, buffer( + "ST300EVT;205173382;07;564;20160322;23:23:18;232e19;+19.288278;-099.128750;000.122;000.00;9;1;478391;11.53;000100;2;1;9498;079324;4.3;1;0.00;0.00;0.00;00000000000000;0;2898E16006000058:-20.8;2861626006000039:+2.5;:")); + + verifyPosition(decoder, buffer( + "ST600STT;008349958;35;523;20181112;00:49:30;0bf10d4e;334;20;2f19;22;+20.552718;-100.824478;050.021;095.41;12;1;1303603;14.30;10000000;4;8911;001987;4.1;0;0.00;;;;00000000000000;0;2826C8A70800000C:+26.6;:;:")); + + } + + @Test + public void testDecodeRpm() throws Exception { + + var decoder = inject(new SuntechProtocolDecoder(null)); + + decoder.setHbm(true); + decoder.setIncludeRpm(true); + + verifyAttribute(decoder, buffer( + "ST300STT;907131077;04;706;20190227;23:59:34;cc719;-12.963490;-038.499587;000.067;000.00;7;1;57095;12.50;000000;1;0337;000207;0.0;1;0;012E717F010000;1"), + Position.KEY_RPM, 0); + + } + + @Test + public void testDecodeHours() throws Exception { + + var decoder = inject(new SuntechProtocolDecoder(null)); + + decoder.setHbm(true); + + verifyAttribute(decoder, buffer( + "ST300ALT;007239104;40;313;20190112;01:07:16;c99139;+04.703287;-074.148897;000.000;189.72;21;1;425512;12.61;100000;33;003188;4.1;1"), + Position.KEY_HOURS, 3188 * 60000L); + + } + + @Test + public void testDecodeDriver() throws Exception { + + var decoder = inject(new SuntechProtocolDecoder(null)); + + verifyAttribute(decoder, buffer( + "ST300HTE;511050566;45;308;20200909;13:38:38;0;12.50;001354;0.0;1;0;1;1;0;-27.636632;-052.277933;-27.636675;-052.277947;000.000;002.296;0;00000000000000"), + Position.KEY_DRIVER_UNIQUE_ID, "00000000000000"); + + verifyAttribute(decoder, buffer( + "ST300HTE;100850001;04;248;20110101;00:13:52;167559;12.28;004005;0.0;1;0;3;3;0;-22.881018;-047.070831;-22.881018;-047.070831;000.000;000.000;0;0;3;0;0;0;01E04D44160000"), + Position.KEY_DRIVER_UNIQUE_ID, "01E04D44160000"); + + } + } -- cgit v1.2.3 From 397d959f7dc61d9df241e589910ff4e15d5145d8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 10 Jan 2023 07:48:06 -0800 Subject: Decode MD500S temperature --- .../java/org/traccar/protocol/MeitrackProtocolDecoder.java | 10 ++++++++++ .../java/org/traccar/protocol/MeitrackProtocolDecoderTest.java | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 82c8f0087..bf8ceaf8a 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -528,6 +528,16 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); int length = buf.readUnsignedByte(); switch (id) { + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + case 0x30: + case 0x31: + position.set(Position.PREFIX_TEMP + buf.readUnsignedByte(), buf.readShortLE() * 0.01); + break; case 0xFE31: buf.readUnsignedByte(); // alarm protocol buf.readUnsignedByte(); // alarm type diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 67b83ebd9..ce0a1e922 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); + verifyPositions(decoder, binary( + "24246a3138312c3836343238313034313930383330332c4343452c00000000010093001f000505000600070714001502090800000900000a00000b0000160a001706001904001ad90440230006023279570103305ccc0604f536492b0c510300000d495701001c014000000b0e0ccc010000922781abb90c00002a030034212b03008b082c030053082d03009e082e030034212f030034213003003421310300342149090400000000000000004b07010104574946492a36310d0a")); + verifyPositions(decoder, binary( "2424423233322c3836323039303035303030323831332c4343452c0400000003004400110004050006000700fe6962060800000900000a00000b00001aef044023000602d65fbcfd03173b9c0804cc76ae2a0c14ae1b000d00aa0d001c01000000014b030101003f00100004050006000700fe695f060800000900000a00000b00001aea044016000502d65fbcfd03173b9c0804cf76ae2a0c14ae1b000d03aa0d00014b030101003f00100004050006000700fe695f060800000900000a00000b00001aed044001000502d65fbcfd03173b9c0804d076ae2a0c14ae1b000d04aa0d00014b030101002a30460d0a")); -- cgit v1.2.3 From 78f60fac965bab4a2172884591243bb43ca95a50 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 11 Jan 2023 16:34:15 -0800 Subject: Add MT821 test cases --- src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java index 678007f5c..59ed997e5 100644 --- a/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java @@ -11,6 +11,15 @@ public class EskyProtocolDecoderTest extends ProtocolTest { var decoder = inject(new EskyProtocolDecoder(null)); + verifyNull(decoder, text( + "ET;7;864431049985585;R3;230111233458+1,137052172,12320,505,87+5+4205+4")); + + verifyNull(decoder, text( + "ET;7;864431049985585;R0;0+230111233558+0.00000+0.00000+0.00+0+2+4206+5")); + + verifyNull(decoder, text( + "ET;7;864431049985585;RC;ES821_BULLANT_B1.08V3.4_20200304+1+60+12+82800+0+40+1+0,0.00000,0.00000,0|0,0.00000,0.00000,0|0,0.00000,0.00000,0|0,0.00000,0.00000,0|0,0.00000,0.00000,0+3")); + verifyAttribute(decoder, text( "ET;0;860337031066546;R;9+200717114059+41.32053+19.80761+0.30+0+0x2+8+40381744+0+1409+11"), Position.KEY_BATTERY, 14.09); -- cgit v1.2.3 From 1fd8b0db0586754e13b0c87457fd717f74effafe Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 11 Jan 2023 16:34:42 -0800 Subject: Revert "Add MT821 test cases" This reverts commit 78f60fac965bab4a2172884591243bb43ca95a50. --- src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java index 59ed997e5..678007f5c 100644 --- a/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/EskyProtocolDecoderTest.java @@ -11,15 +11,6 @@ public class EskyProtocolDecoderTest extends ProtocolTest { var decoder = inject(new EskyProtocolDecoder(null)); - verifyNull(decoder, text( - "ET;7;864431049985585;R3;230111233458+1,137052172,12320,505,87+5+4205+4")); - - verifyNull(decoder, text( - "ET;7;864431049985585;R0;0+230111233558+0.00000+0.00000+0.00+0+2+4206+5")); - - verifyNull(decoder, text( - "ET;7;864431049985585;RC;ES821_BULLANT_B1.08V3.4_20200304+1+60+12+82800+0+40+1+0,0.00000,0.00000,0|0,0.00000,0.00000,0|0,0.00000,0.00000,0|0,0.00000,0.00000,0|0,0.00000,0.00000,0+3")); - verifyAttribute(decoder, text( "ET;0;860337031066546;R;9+200717114059+41.32053+19.80761+0.30+0+0x2+8+40381744+0+1409+11"), Position.KEY_BATTERY, 14.09); -- cgit v1.2.3 From ec13d084baa823da3a520bc1a69178e58138abe3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 11 Jan 2023 16:37:43 -0800 Subject: Fix SQL query --- src/main/java/org/traccar/storage/query/Order.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/storage/query/Order.java b/src/main/java/org/traccar/storage/query/Order.java index b41f145e9..f10970381 100644 --- a/src/main/java/org/traccar/storage/query/Order.java +++ b/src/main/java/org/traccar/storage/query/Order.java @@ -27,7 +27,7 @@ public class Order { public Order(String column, boolean descending, int limit) { this.column = column; - this.descending = false; + this.descending = descending; this.limit = limit; } -- cgit v1.2.3 From 4f9c8cca508d4e07823e7fd4c9e4911f042ea63f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 13 Jan 2023 09:20:22 -0800 Subject: Add Granit Navigator 207 test --- .../traccar/protocol/NdtpV6ProtocolDecoderTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/test/java/org/traccar/protocol/NdtpV6ProtocolDecoderTest.java diff --git a/src/test/java/org/traccar/protocol/NdtpV6ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NdtpV6ProtocolDecoderTest.java new file mode 100644 index 000000000..c63c19a29 --- /dev/null +++ b/src/test/java/org/traccar/protocol/NdtpV6ProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class NdtpV6ProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + var decoder = inject(new NdtpV6ProtocolDecoder(null)); + + verifyAttributes(decoder, binary( + "7e7e3b000200334202000000000000000064000100000000000600020002034f0c0200000400000000000033353135313330353131393430353532353030323632373237343836363500")); + + } + +} -- cgit v1.2.3 From 922f2f26f880c92b984435987319d46750d929a0 Mon Sep 17 00:00:00 2001 From: e-macgregor <122734173+e-macgregor@users.noreply.github.com> Date: Sun, 15 Jan 2023 08:29:04 -0600 Subject: Added missing "StatusReq" --- src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java index b298adc5a..a4faacf13 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java @@ -99,7 +99,7 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_REBOOT_DEVICE: return formatCommand(command, prefix + "CMD;%s;02;Reboot\r", Command.KEY_UNIQUE_ID); case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, prefix + "CMD;%s;02;\r", Command.KEY_UNIQUE_ID); + return formatCommand(command, prefix + "CMD;%s;02;StatusReq\r", Command.KEY_UNIQUE_ID); case Command.TYPE_OUTPUT_CONTROL: if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { return formatCommand(command, prefix + "CMD;%s;02;Enable%s\r", -- cgit v1.2.3 From 1417098fa45a3060f17e0cca6d8226b12e7f174e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 15 Jan 2023 17:37:20 -0800 Subject: Remove default admin --- schema/changelog-4.0-clean.xml | 8 -------- src/main/java/org/traccar/api/resource/ServerResource.java | 8 ++++++++ src/main/java/org/traccar/api/resource/SessionResource.java | 5 ++++- src/main/java/org/traccar/api/resource/UserResource.java | 5 +++++ src/main/java/org/traccar/helper/model/UserUtil.java | 11 +++++++++++ src/main/java/org/traccar/model/Server.java | 12 ++++++++++++ src/main/java/org/traccar/storage/query/Request.java | 6 +++--- 7 files changed, 43 insertions(+), 12 deletions(-) diff --git a/schema/changelog-4.0-clean.xml b/schema/changelog-4.0-clean.xml index f3f814eba..b4d8ac0ba 100644 --- a/schema/changelog-4.0-clean.xml +++ b/schema/changelog-4.0-clean.xml @@ -620,14 +620,6 @@ - - - - - - - - diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java index e7f0b93ca..4b7ee9189 100644 --- a/src/main/java/org/traccar/api/resource/ServerResource.java +++ b/src/main/java/org/traccar/api/resource/ServerResource.java @@ -16,6 +16,7 @@ package org.traccar.api.resource; import org.traccar.api.BaseResource; +import org.traccar.helper.model.UserUtil; import org.traccar.mail.MailManager; import org.traccar.geocoder.Geocoder; import org.traccar.helper.Log; @@ -65,6 +66,13 @@ public class ServerResource extends BaseResource { server.setEmailEnabled(mailManager.getEmailEnabled()); server.setGeocoderEnabled(geocoder != null); User user = permissionsService.getUser(getUserId()); + if (user != null) { + if (user.getAdministrator()) { + server.setStorageSpace(Log.getStorageSpace()); + } + } else { + server.setNewServer(UserUtil.isEmpty(storage)); + } if (user != null && user.getAdministrator()) { server.setStorageSpace(Log.getStorageSpace()); } diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index 1e984fbd0..7025d5fa7 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -110,7 +110,10 @@ public class SessionResource extends BaseResource { } else { - return permissionsService.getUser(userId); + User user = permissionsService.getUser(userId); + if (user != null) { + return user; + } } diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index 91875ef51..e41ebbe61 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -19,6 +19,7 @@ import org.traccar.api.BaseObjectResource; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.LogAction; +import org.traccar.helper.model.UserUtil; import org.traccar.model.ManagedUser; import org.traccar.model.Permission; import org.traccar.model.User; @@ -98,6 +99,10 @@ public class UserResource extends BaseObjectResource { } } + if (UserUtil.isEmpty(storage)) { + entity.setAdministrator(true); + } + entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); storage.updateObject(entity, new Request( new Columns.Include("hashedPassword", "salt"), diff --git a/src/main/java/org/traccar/helper/model/UserUtil.java b/src/main/java/org/traccar/helper/model/UserUtil.java index 9919e1d95..9f93afeae 100644 --- a/src/main/java/org/traccar/helper/model/UserUtil.java +++ b/src/main/java/org/traccar/helper/model/UserUtil.java @@ -17,6 +17,11 @@ package org.traccar.helper.model; import org.traccar.model.Server; import org.traccar.model.User; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Order; +import org.traccar.storage.query.Request; import java.util.TimeZone; @@ -25,6 +30,12 @@ public final class UserUtil { private UserUtil() { } + public static boolean isEmpty(Storage storage) throws StorageException { + return storage.getObjects(User.class, new Request( + new Columns.Include("id"), + new Order("id", false, 1))).isEmpty(); + } + public static String getDistanceUnit(Server server, User user) { return lookupStringAttribute(server, user, "distanceUnit", "km"); } diff --git a/src/main/java/org/traccar/model/Server.java b/src/main/java/org/traccar/model/Server.java index 9e248e7bb..73645721b 100644 --- a/src/main/java/org/traccar/model/Server.java +++ b/src/main/java/org/traccar/model/Server.java @@ -249,4 +249,16 @@ public class Server extends ExtendedModel implements UserRestrictions { this.storageSpace = storageSpace; } + private boolean newServer; + + @QueryIgnore + public boolean getNewServer() { + return newServer; + } + + @QueryIgnore + public void setNewServer(boolean newServer) { + this.newServer = newServer; + } + } diff --git a/src/main/java/org/traccar/storage/query/Request.java b/src/main/java/org/traccar/storage/query/Request.java index 6e9cecc63..b9c2c963c 100644 --- a/src/main/java/org/traccar/storage/query/Request.java +++ b/src/main/java/org/traccar/storage/query/Request.java @@ -33,11 +33,11 @@ public class Request { this(columns, condition, null); } - public Request(Columns columns, Condition condition, Order order) { - this(columns, condition, order, null); + public Request(Columns columns, Order order) { + this(columns, null, order); } - public Request(Columns columns, Condition condition, Order order, Limit limit) { + public Request(Columns columns, Condition condition, Order order) { this.columns = columns; this.condition = condition; this.order = order; -- cgit v1.2.3 From 85501f9cf4918d5eee345f83aed7a31eecb26b8d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 16 Jan 2023 07:01:42 -0800 Subject: Fix temperature index --- src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index bf8ceaf8a..343141dca 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -536,7 +536,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case 0x2F: case 0x30: case 0x31: - position.set(Position.PREFIX_TEMP + buf.readUnsignedByte(), buf.readShortLE() * 0.01); + buf.readUnsignedByte(); // label + position.set(Position.PREFIX_TEMP + (id - 0x2A), buf.readShortLE() * 0.01); break; case 0xFE31: buf.readUnsignedByte(); // alarm protocol -- cgit v1.2.3